diff --git a/input/otlp/traces.go b/input/otlp/traces.go index a56b8c87..cbb2f522 100644 --- a/input/otlp/traces.go +++ b/input/otlp/traces.go @@ -82,6 +82,7 @@ const ( attributeStackTrace = "code.stacktrace" // semconv 1.24 or later attributeDataStreamDataset = "data_stream.dataset" attributeDataStreamNamespace = "data_stream.namespace" + attributeGenAiSystem = "gen_ai.system" ) // ConsumeTracesResult contains the number of rejected spans and error message for partial success response. @@ -615,6 +616,10 @@ func TranslateSpan(spanKind ptrace.SpanKind, attributes pcommon.Map, event *mode rpcService string ) + var ( + genAiSystem string + ) + var http modelpb.HTTP var httpRequest modelpb.HTTPRequest var httpResponse modelpb.HTTPResponse @@ -622,7 +627,7 @@ func TranslateSpan(spanKind ptrace.SpanKind, attributes pcommon.Map, event *mode var db modelpb.DB var destinationService modelpb.DestinationService var serviceTarget modelpb.ServiceTarget - var isHTTP, isDatabase, isRPC, isMessaging bool + var isHTTP, isDatabase, isRPC, isMessaging, isGenAi bool var samplerType, samplerParam pcommon.Value attributes.Range(func(kDots string, v pcommon.Value) bool { if isJaeger { @@ -812,6 +817,11 @@ func TranslateSpan(spanKind ptrace.SpanKind, attributes pcommon.Map, event *mode // stacktrace is expected to be large thus un-truncated value is needed event.Code.Stacktrace = v.Str() + // gen_ai.* + case attributeGenAiSystem: + genAiSystem = stringval + isGenAi = true + // miscellaneous case "span.kind": // filter out case semconv.AttributePeerService: @@ -991,6 +1001,10 @@ func TranslateSpan(spanKind ptrace.SpanKind, attributes pcommon.Map, event *mode destinationService.Resource = resource } } + case isGenAi: + event.Span.Type = "genai" + event.Span.Subtype = genAiSystem + serviceTarget.Type = event.Span.Type default: // Only set event.Span.Type if not already set if event.Span.Type == "" { diff --git a/input/otlp/traces_test.go b/input/otlp/traces_test.go index 4c6665b4..26a447c3 100644 --- a/input/otlp/traces_test.go +++ b/input/otlp/traces_test.go @@ -1438,6 +1438,16 @@ func TestSpanEventsDataStream(t *testing.T) { } } +func TestGenAiSpan(t *testing.T) { + event := transformSpanWithAttributes(t, map[string]interface{}{ + "gen_ai.system": "openai", + }) + + assert.Equal(t, "genai", event.Span.Type) + assert.Equal(t, "openai", event.Span.Subtype) + assert.Equal(t, "", event.Span.Action) +} + func transformTransactionWithAttributes(t *testing.T, attrs map[string]interface{}, configFns ...func(ptrace.Span)) *modelpb.APMEvent { traces, spans := newTracesSpans() otelSpan := spans.Spans().AppendEmpty()