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:


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

OpenTelemetry Jaeger Thrift Jaeger Proto Notes
Span.TraceId Span.traceIdLow/High Span.trace_id See IDs
Span.ParentId Span.parentSpanId as SpanReference See Parent ID
Span.SpanId Span.spanId Span.span_id
Span.TraceState TBD TBD
Span.Name Span.operationName Span.operation_name
Span.Kind Span.tags[“span.kind”] same See SpanKind for values mapping
Span.StartTime Span.startTime Span.start_time See Unit of time
Span.EndTime Span.duration same Calculated as EndTime - StartTime. See also Unit of time
Span.Attributes Span.tags same See Attributes for data types for the mapping.
Span.DroppedAttributesCount Add to Span.tags same See Dropped Attributes Count for tag name to use.
Span.Events Span.logs same See Events for the mapping format.
Span.DroppedEventsCount Add to Span.tags same See Dropped Events Count for tag name to use.
Span.Links Span.references same See Links
Span.DroppedLinksCount Add to Span.tags same See Dropped Links Count for tag name to use.
Span.Status Add to Span.tags same See Status for tag names to use.


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


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 attribute of the service resource. If no is contained in a Span’s Resource, that field MUST be populated from the default Resource.


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.:


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


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.

OpenTelemetry Jaeger
SpanKind.CLIENT "client"
SpanKind.SERVER "server"
SpanKind.CONSUMER "consumer"
SpanKind.PRODUCER "producer"
SpanKind.INTERNAL do 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.


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.


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 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 Field Jaeger Attribute
name event
  • If OpenTelemetry Event contains an attributes with the key event, it should take precedence over Event’s name field.