OpenTelemetry to Jaeger Transformation

Status: Stable

This document defines the transformation between OpenTelemetry and Jaeger Spans. The generic transformation rules specified here also apply. If a particular generic transformation rule and the rule in this document contradict then the rule in this document MUST be used.

Jaeger accepts spans in two formats:

See also:

Summary

The following table summarizes the major transformations between OpenTelemetry and Jaeger.

OpenTelemetryJaeger ThriftJaeger ProtoNotes
Span.TraceIdSpan.traceIdLow/HighSpan.trace_idSee IDs
Span.ParentIdSpan.parentSpanIdas SpanReferenceSee Parent ID
Span.SpanIdSpan.spanIdSpan.span_id
Span.TraceStateTBDTBD
Span.NameSpan.operationNameSpan.operation_name
Span.KindSpan.tags[“span.kind”]sameSee SpanKind for values mapping
Span.StartTimeSpan.startTimeSpan.start_timeSee Unit of time
Span.EndTimeSpan.durationsameCalculated as EndTime - StartTime. See also Unit of time
Span.AttributesSpan.tagssameSee Attributes for data types for the mapping.
Span.DroppedAttributesCountAdd to Span.tagssameSee Dropped Attributes Count for tag name to use.
Span.EventsSpan.logssameSee Events for the mapping format.
Span.DroppedEventsCountAdd to Span.tagssameSee Dropped Events Count for tag name to use.
Span.LinksSpan.referencessameSee Links
Span.DroppedLinksCountAdd to Span.tagssameSee Dropped Links Count for tag name to use.
Span.StatusAdd to Span.tagssameSee Status for tag names to use.

Mappings

This section discusses the details of the transformations between OpenTelemetry and Jaeger.

Resource

OpenTelemetry resources MUST be mapped to Jaeger’s Span.Process tags. Multiple resources can exist for a single process and exporters need to handle this case accordingly.

Critically, Jaeger backend depends on Span.Process.ServiceName to identify the service that produced the spans. That field MUST be populated from the service.name attribute of the service resource. If no service.name is contained in a Span’s Resource, that field MUST be populated from the default Resource.

IDs

Trace and span IDs in Jaeger are random sequences of bytes. However, Thrift model represents IDs using i64 type, or in case of a 128-bit wide Trace ID as two i64 fields traceIdLow and traceIdHigh. The bytes MUST be converted to/from unsigned ints using Big Endian byte order, e.g. [0x10, 0x00, 0x00, 0x00] == 268435456. The unsigned ints MUST be converted to i64 by re-interpreting the existing 64bit value as signed i64. For example (in Go):

var (
    id       []byte = []byte{0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
    unsigned uint64 = binary.BigEndian.Uint64(id)
    signed   int64  = int64(unsigned)
)
fmt.Println("unsigned:", unsigned)
fmt.Println("  signed:", signed)
// Output:
// unsigned: 18374686479671623680
//   signed: -72057594037927936

Parent ID

Jaeger Thrift format allows capturing parent ID in a top-level Span field. Jaeger Proto format does not support parent ID field; instead the parent MUST be recorded as a SpanReference of type CHILD_OF, e.g.:

    SpanReference(
        ref_type=opentracing.CHILD_OF,
        trace_id=span.context.trace_id,
        span_id=parent_id,
    )

This span reference MUST be the first in the list of references.

SpanKind

OpenTelemetry SpanKind field MUST be encoded as span.kind tag in Jaeger span, except for SpanKind.INTERNAL, which SHOULD NOT be translated to a tag.

OpenTelemetryJaeger
SpanKind.CLIENT"client"
SpanKind.SERVER"server"
SpanKind.CONSUMER"consumer"
SpanKind.PRODUCER"producer"
SpanKind.INTERNALdo not add span.kind tag

Unit of time

In Jaeger Thrift format the timestamps and durations MUST be represented in microseconds (since epoch for timestamps). If the original value in OpenTelemetry is expressed in nanoseconds, it MUST be rounded or truncated to microseconds.

In Jaeger Proto format the timestamps and durations MUST be represented with nanosecond precision using google.protobuf.Timestamp and google.protobuf.Duration types.

Status

The Status is recorded as Span tags. See Status for tag names to use.

Error flag

When Span Status is set to ERROR, an error span tag MUST be added with the Boolean value of true. The added error tag MAY override any previous value.

Attributes

OpenTelemetry Span Attribute(s) MUST be reported as tags to Jaeger.

Primitive types MUST be represented by the corresponding types of Jaeger tags.

Array values MUST be serialized to string like a JSON list as mentioned in semantic conventions.

OpenTelemetry Link(s) MUST be converted to SpanReference(s) in Jaeger, using FOLLOWS_FROM reference type. The Link’s attributes cannot be represented in Jaeger explicitly. The exporter MAY additionally convert Link(s) to span Log(s):

  • use Span start time as the timestamp of the Log
  • set Log tag event=link
  • set Log tags trace_id and span_id from the respective SpanContext’s fields
  • store Link’s attributes as Log tags

Span references generated from Link(s) MUST be added after the span reference generated from Parent ID, if any.

Events

Events MUST be converted to Jaeger Logs. OpenTelemetry Event’s time_unix_nano and attributes fields map directly to Jaeger Log’s timestamp and fields fields. Jaeger Log has no direct equivalent for OpenTelemetry Event’s name field but OpenTracing semantic conventions specify some special attribute names here. OpenTelemetry Event’s name field should be added to Jaeger Log’s fields map as follows:

OpenTelemetry Event FieldJaeger Attribute
nameevent
  • If OpenTelemetry Event contains an attributes with the key event, it should take precedence over Event’s name field.