Skip to content

Commit

Permalink
Update OTLP-Jaeger translation of events according to the spec (#10273)
Browse files Browse the repository at this point in the history
Name field of a span event was mapped to a Jaeger log with `message` key which has a different meaning in OpenTracing specification: https://github.com/opentracing/specification/blob/master/semantic_conventions.md#log-fields-table.

This change update OTLP-Jaeger translation of Span events according to the OTel Spec saying that `Name` field should be mapped to `event` Jaeger attribute: https://github.com/open-telemetry/opentelemetry-specification/blob/34b907207f3dfe1635a35c4cdac6b6ab3a495e18/specification/trace/sdk_exporters/jaeger.md#events
  • Loading branch information
dmitryax authored May 25, 2022
1 parent 50e8ecb commit eea4940
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
- `datadogexporter`: add error checks for datadog exporter (#9964)
- `datadogexporter`: Fix host aliases not being properly sent to the Datadog backend (#9748)
- `groupbyattrsprocessor`: copied aggregationtemporality when grouping metrics. (#9088)
- `jaeger`: Update OTLP-Jaeger translation of span events according to the OTel Spec: use `event` log field instead
of `message` to represent OTel Span Event Name (#10273)
- `mongodbreceiver`: Fix issue where receiver startup could hang (#10111)
- `transformprocessor`: Fix issue where metric.aggregation_temporality and metric.is_monotic were not actually gettable or settable (#10197)
- `signalfxexporter`: Emit prometheus compatible histogram/summary to signalfx #10299
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import (

// Some of the keys used to represent OTLP constructs as tags or annotations in other formats.
const (
TagMessage = "message"

TagSpanKind = "span.kind"

TagError = "error"
Expand Down
4 changes: 4 additions & 0 deletions pkg/translator/jaeger/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const (
statusOk = "OK"
)

// eventNameAttr is a Jaeger log field key used to represent OTel Span Event Name as defined by the OpenTelemetry Specification:
// https://github.com/open-telemetry/opentelemetry-specification/blob/34b907207f3dfe1635a35c4cdac6b6ab3a495e18/specification/trace/sdk_exporters/jaeger.md#events
const eventNameAttr = "event"

var (
// errType indicates that a value is not convertible to the target type.
errType = errors.New("invalid type")
Expand Down
4 changes: 2 additions & 2 deletions pkg/translator/jaeger/jaegerproto_to_traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,9 +340,9 @@ func jLogsToSpanEvents(logs []model.Log, dest ptrace.SpanEventSlice) {
attrs.Clear()
attrs.EnsureCapacity(len(log.Fields))
jTagsToInternalAttributes(log.Fields, attrs)
if name, ok := attrs.Get(tracetranslator.TagMessage); ok {
if name, ok := attrs.Get(eventNameAttr); ok {
event.SetName(name.StringVal())
attrs.Remove(tracetranslator.TagMessage)
attrs.Remove(eventNameAttr)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/translator/jaeger/jaegerproto_to_traces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ func generateProtoSpan() *model.Span {
Timestamp: testSpanEventTime,
Fields: []model.KeyValue{
{
Key: tracetranslator.TagMessage,
Key: eventNameAttr,
VType: model.ValueType_STRING,
VStr: "event-with-attr",
},
Expand Down Expand Up @@ -654,7 +654,7 @@ func generateProtoSpanWithTraceState() *model.Span {
Timestamp: testSpanEventTime,
Fields: []model.KeyValue{
{
Key: tracetranslator.TagMessage,
Key: eventNameAttr,
VType: model.ValueType_STRING,
VStr: "event-with-attr",
},
Expand Down
4 changes: 2 additions & 2 deletions pkg/translator/jaeger/jaegerthrift_to_traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ func jThriftLogsToSpanEvents(logs []*jaeger.Log, dest ptrace.SpanEventSlice) {
attrs.Clear()
attrs.EnsureCapacity(len(log.Fields))
jThriftTagsToInternalAttributes(log.Fields, attrs)
if name, ok := attrs.Get(tracetranslator.TagMessage); ok {
if name, ok := attrs.Get(eventNameAttr); ok {
event.SetName(name.StringVal())
attrs.Remove(tracetranslator.TagMessage)
attrs.Remove(eventNameAttr)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/translator/jaeger/jaegerthrift_to_traces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func generateThriftSpan() *jaeger.Span {
Timestamp: eventTs,
Fields: []*jaeger.Tag{
{
Key: tracetranslator.TagMessage,
Key: eventNameAttr,
VType: jaeger.TagType_STRING,
VStr: &eventName,
},
Expand Down
5 changes: 3 additions & 2 deletions pkg/translator/jaeger/traces_to_jaegerproto.go
Original file line number Diff line number Diff line change
Expand Up @@ -292,9 +292,10 @@ func spanEventsToJaegerProtoLogs(events ptrace.SpanEventSlice) []model.Log {
for i := 0; i < events.Len(); i++ {
event := events.At(i)
fields := make([]model.KeyValue, 0, event.Attributes().Len()+1)
if event.Name() != "" {
_, eventAttrFound := event.Attributes().Get(eventNameAttr)
if event.Name() != "" && !eventAttrFound {
fields = append(fields, model.KeyValue{
Key: tracetranslator.TagMessage,
Key: eventNameAttr,
VType: model.ValueType_STRING,
VStr: event.Name(),
})
Expand Down
39 changes: 39 additions & 0 deletions pkg/translator/jaeger/traces_to_jaegerproto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,20 @@ func TestInternalTracesToJaegerProto(t *testing.T) {
},
err: nil,
},

{
name: "span-with-span-event-attribute",
td: generateTracesOneSpanNoResourceWithEventAttribute(),
jb: &model.Batch{
Process: &model.Process{
ServiceName: tracetranslator.ResourceNoServiceName,
},
Spans: []*model.Span{
generateJProtoSpanWithEventAttribute(),
},
},
err: nil,
},
}

for _, test := range tests {
Expand Down Expand Up @@ -333,6 +347,31 @@ func TestInternalTracesToJaegerProtoBatchesAndBack(t *testing.T) {
}
}

func generateTracesOneSpanNoResourceWithEventAttribute() ptrace.Traces {
td := generateTracesOneSpanNoResource()
event := td.ResourceSpans().At(0).ScopeSpans().At(0).Spans().At(0).Events().At(0)
event.SetName("must-be-ignorred")
event.Attributes().InsertString("event", "must-be-used-instead-of-event-name")
return td
}

func generateJProtoSpanWithEventAttribute() *model.Span {
span := generateProtoSpan()
span.Logs[0].Fields = []model.KeyValue{
{
Key: "span-event-attr",
VType: model.ValueType_STRING,
VStr: "span-event-attr-val",
},
{
Key: eventNameAttr,
VType: model.ValueType_STRING,
VStr: "must-be-used-instead-of-event-name",
},
}
return span
}

// generateProtoChildSpanWithErrorTags generates a jaeger span to be used in
// internal->jaeger translation test. It supposed to be the same as generateProtoChildSpan
// that used in jaeger->internal, but jaeger->internal translation infers status code from http status if
Expand Down

0 comments on commit eea4940

Please sign in to comment.