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  }