github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/helper/pipeline_event_helper.go (about) 1 package helper 2 3 import ( 4 "fmt" 5 "sync" 6 "time" 7 8 "github.com/alibaba/ilogtail/pkg/models" 9 "github.com/alibaba/ilogtail/pkg/protocol" 10 "github.com/alibaba/ilogtail/pkg/util" 11 ) 12 13 var LogEventPool = sync.Pool{ 14 New: func() interface{} { 15 return new(protocol.LogEvent) 16 }, 17 } 18 19 func CreateLogEvent(t time.Time, enableTimestampNano bool, fields map[string]string) (*protocol.LogEvent, error) { 20 logEvent := LogEventPool.Get().(*protocol.LogEvent) 21 logEvent.Timestamp = uint64(t.Unix())*1e9 + uint64(t.Nanosecond()) 22 if len(logEvent.Contents) < len(fields) { 23 slice := make([]*protocol.LogEvent_Content, len(logEvent.Contents), len(fields)) 24 copy(slice, logEvent.Contents) 25 logEvent.Contents = slice 26 } else { 27 logEvent.Contents = logEvent.Contents[:len(fields)] 28 } 29 i := 0 30 rawSize := 0 31 for key, val := range fields { 32 if i >= len(logEvent.Contents) { 33 logEvent.Contents = append(logEvent.Contents, &protocol.LogEvent_Content{}) 34 } 35 logEvent.Contents[i].Key = util.ZeroCopyStringToBytes(key) 36 logEvent.Contents[i].Value = util.ZeroCopyStringToBytes(val) 37 i++ 38 rawSize += len(val) 39 } 40 logEvent.RawSize = uint64(rawSize) 41 return logEvent, nil 42 } 43 44 func CreateLogEventByArray(t time.Time, enableTimestampNano bool, columns []string, values []string) (*protocol.LogEvent, error) { 45 logEvent := LogEventPool.Get().(*protocol.LogEvent) 46 logEvent.Timestamp = uint64(t.Unix())*1e9 + uint64(t.Nanosecond()) 47 logEvent.Contents = make([]*protocol.LogEvent_Content, 0, len(columns)) 48 if len(columns) != len(values) { 49 return nil, fmt.Errorf("columns and values not equal") 50 } 51 rawSize := 0 52 for index := range columns { 53 if index >= len(logEvent.Contents) { 54 logEvent.Contents = append(logEvent.Contents, &protocol.LogEvent_Content{}) 55 } 56 logEvent.Contents[index].Key = util.ZeroCopyStringToBytes(columns[index]) 57 logEvent.Contents[index].Value = util.ZeroCopyStringToBytes(values[index]) 58 rawSize += len(values[index]) 59 } 60 logEvent.RawSize = uint64(rawSize) 61 return logEvent, nil 62 } 63 64 func CreateLogEventByLegacyRawLog(log *protocol.Log) (*protocol.LogEvent, error) { 65 logEvent := LogEventPool.Get().(*protocol.LogEvent) 66 logEvent.Timestamp = uint64(log.GetTime())*1e9 + uint64(log.GetTimeNs()) 67 logEvent.Contents = make([]*protocol.LogEvent_Content, 0, len(log.Contents)) 68 rawSize := 0 69 for i, logC := range log.Contents { 70 if i >= len(logEvent.Contents) { 71 logEvent.Contents = append(logEvent.Contents, &protocol.LogEvent_Content{}) 72 } 73 logEvent.Contents[i].Key = util.ZeroCopyStringToBytes(logC.Key) 74 logEvent.Contents[i].Value = util.ZeroCopyStringToBytes(logC.Value) 75 rawSize += len(logC.Value) 76 } 77 logEvent.RawSize = uint64(rawSize) 78 return logEvent, nil 79 } 80 81 func TransferLogEventToPB(log *models.Log) (*protocol.LogEvent, error) { 82 logEvent := LogEventPool.Get().(*protocol.LogEvent) 83 logEvent.Timestamp = log.GetTimestamp() 84 logEvent.Contents = make([]*protocol.LogEvent_Content, 0, log.Contents.Len()) 85 for k, v := range log.Contents.Iterator() { 86 cont := &protocol.LogEvent_Content{ 87 Key: util.ZeroCopyStringToBytes(k), 88 Value: util.ZeroCopyStringToBytes(v.(string)), 89 } 90 logEvent.Contents = append(logEvent.Contents, cont) 91 } 92 logEvent.Level = util.ZeroCopyStringToBytes(log.GetLevel()) 93 logEvent.FileOffset = log.GetOffset() 94 logEvent.RawSize = log.GetRawSize() 95 return logEvent, nil 96 } 97 98 func TransferMetricEventToPB(metric *models.Metric) (*protocol.MetricEvent, error) { 99 var metricEvent protocol.MetricEvent 100 metricEvent.Timestamp = metric.GetTimestamp() 101 metricEvent.Name = util.ZeroCopyStringToBytes(metric.GetName()) 102 if metric.GetValue().IsSingleValue() { 103 metricEvent.Value = &protocol.MetricEvent_UntypedSingleValue{UntypedSingleValue: &protocol.UntypedSingleValue{Value: metric.Value.GetSingleValue()}} 104 } else { 105 return nil, fmt.Errorf("unsupported metric value type") 106 } 107 metricEvent.Tags = make(map[string][]byte, metric.GetTags().Len()) 108 for k, v := range metric.GetTags().Iterator() { 109 metricEvent.Tags[k] = util.ZeroCopyStringToBytes(v) 110 } 111 return &metricEvent, nil 112 } 113 114 func TransferSpanEventToPB(span *models.Span) (*protocol.SpanEvent, error) { 115 var spanEvent protocol.SpanEvent 116 spanEvent.Timestamp = span.GetTimestamp() 117 spanEvent.TraceID = util.ZeroCopyStringToBytes(span.GetTraceID()) 118 spanEvent.SpanID = util.ZeroCopyStringToBytes(span.GetSpanID()) 119 spanEvent.TraceState = util.ZeroCopyStringToBytes(span.GetTraceState()) 120 spanEvent.ParentSpanID = util.ZeroCopyStringToBytes(span.GetParentSpanID()) 121 spanEvent.Name = util.ZeroCopyStringToBytes(span.GetName()) 122 spanEvent.Kind = protocol.SpanEvent_SpanKind(span.GetKind()) 123 spanEvent.StartTime = span.GetStartTime() 124 spanEvent.EndTime = span.GetEndTime() 125 spanEvent.Tags = make(map[string][]byte, span.GetTags().Len()) 126 for k, v := range span.GetTags().Iterator() { 127 spanEvent.Tags[k] = util.ZeroCopyStringToBytes(v) 128 } 129 spanEvent.Events = make([]*protocol.SpanEvent_InnerEvent, 0, len(span.GetEvents())) 130 for _, srcEvent := range span.GetEvents() { 131 dstEvent := protocol.SpanEvent_InnerEvent{ 132 Timestamp: uint64(srcEvent.Timestamp), 133 Name: util.ZeroCopyStringToBytes(srcEvent.Name), 134 Tags: make(map[string][]byte, srcEvent.Tags.Len()), 135 } 136 for k, v := range srcEvent.Tags.Iterator() { 137 dstEvent.Tags[k] = util.ZeroCopyStringToBytes(v) 138 } 139 spanEvent.Events = append(spanEvent.Events, &dstEvent) 140 } 141 spanEvent.Links = make([]*protocol.SpanEvent_SpanLink, 0, len(span.GetLinks())) 142 for _, srcLink := range span.GetLinks() { 143 dstLink := protocol.SpanEvent_SpanLink{ 144 TraceID: util.ZeroCopyStringToBytes(srcLink.TraceID), 145 SpanID: util.ZeroCopyStringToBytes(srcLink.SpanID), 146 TraceState: util.ZeroCopyStringToBytes(srcLink.TraceState), 147 Tags: make(map[string][]byte, srcLink.Tags.Len()), 148 } 149 for k, v := range srcLink.Tags.Iterator() { 150 dstLink.Tags[k] = util.ZeroCopyStringToBytes(v) 151 } 152 spanEvent.Links = append(spanEvent.Links, &dstLink) 153 } 154 spanEvent.Status = protocol.SpanEvent_StatusCode(span.GetStatus()) 155 return &spanEvent, nil 156 } 157 158 func CreatePipelineEventGroupByLegacyRawLog(logEvents []*protocol.LogEvent, configTag map[string]string, logTags map[string]string, ctx map[string]interface{}) (*protocol.PipelineEventGroup, error) { 159 var pipelineEventGroup protocol.PipelineEventGroup 160 pipelineEventGroup.PipelineEvents = &protocol.PipelineEventGroup_Logs{Logs: &protocol.PipelineEventGroup_LogEvents{Events: logEvents}} 161 pipelineEventGroup.Tags = make(map[string][]byte, len(configTag)+len(logTags)) 162 for k, v := range configTag { 163 pipelineEventGroup.Tags[k] = util.ZeroCopyStringToBytes(v) 164 } 165 for k, v := range logTags { 166 pipelineEventGroup.Tags[k] = util.ZeroCopyStringToBytes(v) 167 } 168 if ctx != nil { 169 if source, ok := ctx["source"].(string); ok { 170 pipelineEventGroup.Metadata = make(map[string][]byte) 171 pipelineEventGroup.Metadata["source_id"] = util.ZeroCopyStringToBytes(source) 172 } 173 } 174 return &pipelineEventGroup, nil 175 } 176 177 func TransferPipelineEventGroupToPB(groupInfo *models.GroupInfo, events []models.PipelineEvent) (*protocol.PipelineEventGroup, error) { 178 var pipelineEventGroup protocol.PipelineEventGroup 179 if len(events) == 0 { 180 return nil, fmt.Errorf("events is empty") 181 } 182 183 eventType := events[0].GetType() 184 switch eventType { 185 case models.EventTypeLogging: 186 logEvents := make([]*protocol.LogEvent, 0, len(events)) 187 for _, event := range events { 188 if logSrc, ok := event.(*models.Log); ok { 189 logDst, _ := TransferLogEventToPB(logSrc) 190 logEvents = append(logEvents, logDst) 191 } 192 } 193 pipelineEventGroup.PipelineEvents = &protocol.PipelineEventGroup_Logs{Logs: &protocol.PipelineEventGroup_LogEvents{Events: logEvents}} 194 case models.EventTypeMetric: 195 metricEvents := make([]*protocol.MetricEvent, 0, len(events)) 196 for _, event := range events { 197 if metricSrc, ok := event.(*models.Metric); ok { 198 metricDst, _ := TransferMetricEventToPB(metricSrc) 199 metricEvents = append(metricEvents, metricDst) 200 } 201 } 202 pipelineEventGroup.PipelineEvents = &protocol.PipelineEventGroup_Metrics{Metrics: &protocol.PipelineEventGroup_MetricEvents{Events: metricEvents}} 203 case models.EventTypeSpan: 204 spanEvents := make([]*protocol.SpanEvent, 0, len(events)) 205 for _, event := range events { 206 if spanSrc, ok := event.(*models.Span); ok { 207 spanDst, _ := TransferSpanEventToPB(spanSrc) 208 spanEvents = append(spanEvents, spanDst) 209 } 210 } 211 pipelineEventGroup.PipelineEvents = &protocol.PipelineEventGroup_Spans{Spans: &protocol.PipelineEventGroup_SpanEvents{Events: spanEvents}} 212 } 213 214 pipelineEventGroup.Tags = make(map[string][]byte, groupInfo.Tags.Len()) 215 for k, v := range groupInfo.Tags.Iterator() { 216 pipelineEventGroup.Tags[k] = util.ZeroCopyStringToBytes(v) 217 } 218 pipelineEventGroup.Metadata = make(map[string][]byte, groupInfo.Metadata.Len()) 219 for k, v := range groupInfo.Metadata.Iterator() { 220 pipelineEventGroup.Metadata[k] = util.ZeroCopyStringToBytes(v) 221 } 222 return &pipelineEventGroup, nil 223 }