Managed Service for OpenTelemetry uses the OpenTracing data model to provide distributed tracing for microservice architectures. This topic covers traces, spans, the data model, and data reporting methods.
OpenTracing is the predecessor of OpenTelemetry. Managed Service for OpenTelemetry supports the OpenTracing data model described here. For the OpenTelemetry standard, see the OpenTelemetry documentation.
Key concepts
| Concept | Description |
|---|---|
| Distributed tracing | A method for tracking requests as they flow through multiple services in a distributed system. |
| Trace | The end-to-end record of a transaction or process in a distributed system. A trace is a directed acyclic graph (DAG) composed of spans. |
| Span | A named, timed unit of work within a trace. |
| SpanContext | Metadata that identifies a span (trace ID, span ID) and carries baggage items across process boundaries. |
| Reference | A causal relationship between two spans. OpenTracing defines two types: ChildOf and FollowsFrom. |
| Tracer | The interface for creating spans and propagating context between services. |
Why distributed tracing matters
Modern applications use microservice architectures where developers adopt methods such as agile development and continuous integration. System architecture has evolved from standalone large-scale software to microservice-based architectures, where a single request can cross dozens of services. These services may be written in different languages, maintained by different teams, and deployed across multiple servers. When a failure occurs in one service, dozens of applications may encounter exceptions, and pinpointing the root cause without end-to-end visibility is impractical.
A distributed tracing system records the full execution path and timing of each request, including the execution process and time consumption of remote method calls. This visibility is essential for troubleshooting system issues and optimizing system performance.
Traces
A trace represents the execution process of a transaction or process in a distributed system. In the OpenTracing standard, a trace is a directed acyclic graph (DAG) composed of multiple spans. Each span represents a named and timed segment that is continuously run in the trace.
For example, a client request might pass through a load balancer, an authentication service, and a billing service before reaching the target resource and returning a response.

Tracing systems typically display this as a timeline, where each row represents a span and the horizontal axis represents time.

Spans
A span represents a single unit of work within a trace. Each span contains the following data:
| Field | Description |
|---|---|
| Operation name | A human-readable label for the work performed (also called the span name). |
| Start timestamp | When the operation began. |
| Finish timestamp | When the operation completed. |
| Tags | Key-value pairs that annotate the span. Keys are strings; values can be strings, booleans, or numbers. |
| Logs | Timestamped key-value pairs that record events during the span lifetime. Keys are strings; values can be any type. |
| SpanContext | Metadata for identifying the span and propagating it across process boundaries. See SpanContext. |
| References | Links to other spans that establish parent-child or sequential relationships. May include zero or multiple related spans. |
Span relationships
OpenTracing defines two types of references between spans:
ChildOf: A parent-child relationship. For example, Span C is a child node of Span A.
FollowsFrom: A sequential relationship. For example, Span G is called after Span F.
The following diagram shows eight spans and their relationships within a single trace:
Causal relationships among spans in a single trace
[Span A] <-- root span
|
+------+------+
| |
[Span B] [Span C] (ChildOf: Span C is a child of Span A)
| |
[Span D] +---+-------+
| |
[Span E] [Span F] >>> [Span G] >>> [Span H]
^
|
(FollowsFrom: Span G follows Span F)The same trace displayed as a timeline:
Time relationships among spans in a single trace
--|-------|-------|-------|-------|-------|-------|-------|-> time
[Span A..........................................................]
[Span B...................................................]
[Span D................................................]
[Span C...............................................]
[Span E.......] [Span F..] [Span G..] [Span H..]SpanContext
A SpanContext carries the metadata needed to identify a span and propagate it across process boundaries. It contains:
Trace ID: A unique identifier for the entire trace.
Span ID: A unique identifier for the individual span.
Baggage items: Key-value pairs that travel with the trace across service boundaries. These key-value pairs must also be transmitted across process boundaries.
Tracer interface
The Tracer is the entry point for creating spans and propagating context across services. It provides the StartSpan method for creating a span, the Extract method for extracting context, and the Inject method for injecting context.
Create a span
Use the StartSpan method to create and start a new span. The method returns a span with the specified operation name and options.
// Method signature:
// StartSpan(operationName string, opts ...StartSpanOption) Span
// Create a root span (no parent).
sp := tracer.StartSpan("GetFeed")
// Create a child span.
sp := tracer.StartSpan(
"GetFeed",
opentracing.ChildOf(parentSpan.Context()),
)Propagate context across services
To pass trace context between services, the Tracer provides two complementary methods:
Inject: Serialize a SpanContext (including the trace ID, span ID, and baggage items) into a carrier (such as HTTP headers) before sending a request to another service.
// Method signature: // Inject(sm SpanContext, format interface{}, carrier interface{}) error carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) err := tracer.Inject( span.Context(), opentracing.HTTPHeaders, carrier, )Extract: Deserialize a SpanContext (including the trace ID, span ID, and baggage items) from a carrier when receiving a request from another service.
// Method signature: // Extract(format interface{}, carrier interface{}) (SpanContext, error) carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) clientContext, err := tracer.Extract( opentracing.HTTPHeaders, carrier, )
Together, Inject and Extract enable end-to-end tracing across process and network boundaries.
Data reporting
Managed Service for OpenTelemetry supports two methods for reporting trace data:
Direct reporting
The application sends trace data directly to the tracing backend without an intermediary.

Report through an agent
The application sends trace data to a local agent (such as Jaeger Agent), which forwards the data to the tracing backend.
