diff --git a/specification/context/api-propagators.md b/specification/context/api-propagators.md index 836b7e8896a..ab58cb52795 100644 --- a/specification/context/api-propagators.md +++ b/specification/context/api-propagators.md @@ -76,7 +76,7 @@ Injects the value into a carrier. For example, into the headers of an HTTP reque Required arguments: - A `Context`. The Propagator MUST retrieve the appropriate value from the `Context` first, such as -`SpanContext`, `Baggage` or another cross-cutting concern context. +`Span`, `Baggage` or another cross-cutting concern context. - The carrier that holds the propagation fields. For example, an outgoing message or HTTP request. #### Extract @@ -93,7 +93,7 @@ Required arguments: - The carrier that holds the propagation fields. For example, an incoming message or http response. Returns a new `Context` derived from the `Context` passed as argument, -containing the extracted value, which can be a `SpanContext`, +containing the extracted value, which can be a `Span`, `Baggage` or another cross-cutting concern context. ## TextMap Propagator diff --git a/specification/overview.md b/specification/overview.md index b3576ac1268..8d27d3517d7 100644 --- a/specification/overview.md +++ b/specification/overview.md @@ -11,7 +11,6 @@ Table of Contents - [Distributed Tracing](#distributed-tracing) * [Trace](#trace) * [Span](#span) - * [SpanContext](#spancontext) * [Links between spans](#links-between-spans) - [Metrics](#metrics) * [Recording raw measurements](#recording-raw-measurements) @@ -96,15 +95,10 @@ Each **Span** encapsulates the following state: - A set of zero or more **Events**, each of which is itself a tuple (timestamp, name, [**Attributes**](./common/common.md#attributes)). The name must be strings. - Parent's **Span** identifier. - [**Links**](#links-between-spans) to zero or more causally-related **Spans** - (via the **SpanContext** of those related **Spans**). -- **SpanContext** identification of a Span. See below. +- Span's propagated information. See below. -### SpanContext - -Represents all the information that identifies **Span** in the **Trace** and -MUST be propagated to child Spans and across process boundaries. A -**SpanContext** contains the tracing identifiers and the options that are -propagated from parent to child **Spans**. +A **Span** has the following identifiers and options which MUST be propagated to child Spans +and across process boundaries. These are propagated from parent to child **Spans**. - **TraceId** is the identifier for a trace. It is worldwide unique with practically sufficient probability by being made as 16 randomly generated @@ -125,9 +119,8 @@ propagated from parent to child **Spans**. ### Links between spans -A **Span** may be linked to zero or more other **Spans** (defined by -**SpanContext**) that are causally related. **Links** can point to -**SpanContexts** inside a single **Trace** or across different **Traces**. +A **Span** may be linked to zero or more other **Spans** that are causally related. +**Links** can point to **Spans** inside a single **Trace** or across different **Traces**. **Links** can be used to represent batched operations where a **Span** was initiated by multiple initiating **Spans**, each representing a single incoming item being processed in the batch. @@ -280,7 +273,7 @@ See the [Context](context/context.md) ## Propagators OpenTelemetry uses `Propagators` to serialize and deserialize cross-cutting concern values -such as `SpanContext` and `Baggage`. Different `Propagator` types define the restrictions +such as `Span` and `Baggage`. Different `Propagator` types define the restrictions imposed by a specific transport and bound to a data type. The Propagators API currently defines one `Propagator` type: diff --git a/specification/trace/api.md b/specification/trace/api.md index 2aec5d92bc6..b15fc560086 100644 --- a/specification/trace/api.md +++ b/specification/trace/api.md @@ -14,16 +14,18 @@ Table of Contents * [Tracing Context Utilities](#tracing-context-utilities) * [Tracer](#tracer) * [Tracer operations](#tracer-operations) -* [SpanContext](#spancontext) - * [Retrieving the TraceId and SpanId](#retrieving-the-traceid-and-spanid) - * [IsValid](#isvalid) - * [IsRemote](#isremote) * [Span](#span) + * [TraceId and SpanId](#traceid-and-spanid) + * [Retrieving the TraceId and SpanId](#retrieving-the-traceid-and-spanid) + * [TraceFlags](#traceflags) + * [TraceState](#tracestate) * [Span creation](#span-creation) * [Determining the Parent Span from a Context](#determining-the-parent-span-from-a-context) * [Add Links](#add-links) * [Span operations](#span-operations) - * [Get Context](#get-context) + * [Accessors](#accessors) + * [IsValid](#isvalid) + * [IsRemote](#isremote) * [IsRecording](#isrecording) * [Set Attributes](#set-attributes) * [Add Events](#add-events) @@ -166,83 +168,6 @@ The `Tracer` MAY provide functions to: These functions MUST delegate to the `Tracing Context Utilities`. -## SpanContext - -A `SpanContext` represents the portion of a `Span` which must be serialized and -propagated along side of a distributed context. `SpanContext`s are immutable. - -The OpenTelemetry `SpanContext` representation conforms to the [W3C TraceContext -specification](https://www.w3.org/TR/trace-context/). It contains two -identifiers - a `TraceId` and a `SpanId` - along with a set of common -`TraceFlags` and system-specific `TraceState` values. - -`TraceId` A valid trace identifier is a 16-byte array with at least one -non-zero byte. - -`SpanId` A valid span identifier is an 8-byte array with at least one non-zero -byte. - -`TraceFlags` contain details about the trace. Unlike TraceState values, -TraceFlags are present in all traces. The current version of the specification -only supports a single flag called [sampled](https://www.w3.org/TR/trace-context/#sampled-flag). - -`TraceState` carries vendor-specific trace identification data, represented as a list -of key-value pairs. TraceState allows multiple tracing -systems to participate in the same trace. It is fully described in the [W3C Trace Context -specification](https://www.w3.org/TR/trace-context/#tracestate-header). - -The API MUST implement methods to create a `SpanContext`. These methods SHOULD be the only way to -create a `SpanContext`. This functionality MUST be fully implemented in the API, and SHOULD NOT be -overridable. - -### Retrieving the TraceId and SpanId - -The API MUST allow retrieving the `TraceId` and `SpanId` in the following forms: - -* Hex - returns the lowercase [hex encoded](https://tools.ietf.org/html/rfc4648#section-8) -`TraceId` (result MUST be a 32-hex-character lowercase string) or `SpanId` -(result MUST be a 16-hex-character lowercase string). -* Binary - returns the binary representation of the `TraceId` (result MUST be a -16-byte array) `SpanId` (result MUST be a 8-byte array). - -The API should not expose details about how they are internally stored. - -### IsValid - -An API called `IsValid`, that returns a boolean value, which is `true` if the SpanContext has a -non-zero TraceID and a non-zero SpanID, MUST be provided. - -### IsRemote - -An API called `IsRemote`, that returns a boolean value, which is `true` if the SpanContext was -propagated from a remote parent, MUST be provided. -When extracting a `SpanContext` through the [Propagators API](../context/api-propagators.md#propagators-api), -`IsRemote` MUST return true, whereas for the SpanContext of any child spans it MUST return false. - -### TraceState - -`TraceState` is a part of [`SpanContext`](./api.md#spancontext), represented by an immutable list of string key/value pairs and -formally defined by the [W3C Trace Context specification](https://www.w3.org/TR/trace-context/#tracestate-header). -Tracing API MUST provide at least the following operations on `TraceState`: - -* Get value for a given key -* Add a new key/value pair -* Update an existing value for a given key -* Delete a key/value pair - -These operations MUST follow the rules described in the [W3C Trace Context specification](https://www.w3.org/TR/trace-context/#mutating-the-tracestate-field). -All mutating operations MUST return a new `TraceState` with the modifications applied. -`TraceState` MUST at all times be valid according to rules specified in [W3C Trace Context specification](https://www.w3.org/TR/trace-context/#tracestate-header-field-values). -Every mutating operations MUST validate input parameters. -If invalid value is passed the operation MUST NOT return `TraceState` containing invalid data -and MUST follow the [general error handling guidelines](../error-handling.md) (e.g. it usually must not return null or throw an exception). - -Please note, since `SpanContext` is immutable, it is not possible to update `SpanContext` with a new `TraceState`. -Such changes then make sense only right before -[`SpanContext` propagation](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/context/api-propagators.md) -or [telemetry data exporting](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#span-exporter). -In both cases, `Propagators` and `SpanExporters` may create a modified `TraceState` copy before serializing it to the wire. - ## Span A `Span` represents a single operation within a trace. Spans can be nested to @@ -252,10 +177,12 @@ the entire operation and, optionally, one or more sub-spans for its sub-operatio `Span`s encapsulate: +- TraceId +- SpanId +- TraceState +- TraceFlags - The span name -- An immutable [`SpanContext`](#spancontext) that uniquely identifies the - `Span` -- A parent span in the form of a [`Span`](#span), [`SpanContext`](#spancontext), +- A parent span in the form of a [`Span`](#span) that is stored in a [Context](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/context/context.md) or null - A [`SpanKind`](#spankind) - A start timestamp @@ -265,6 +192,8 @@ the entire operation and, optionally, one or more sub-spans for its sub-operatio - A list of timestamped [`Event`s](#add-events) - A [`Status`](#set-status). +The TraceId, SpanId, TraceState, and TraceFlags are immutable and set on [creation](#span-creation). + The _span name_ concisely identifies the work represented by the Span, for example, an RPC method name, a function name, or the name of a subtask or stage within a larger computation. @@ -312,12 +241,73 @@ MUST NOT be changed after the `Span`'s end time has been set. `Span`s are not meant to be used to propagate information within a process. To prevent misuse, implementations SHOULD NOT provide access to a `Span`'s -attributes besides its `SpanContext`. +attributes besides its identifiers. Vendors may implement the `Span` interface to effect vendor-specific logic. However, alternative implementations MUST NOT allow callers to create `Span`s directly. All `Span`s MUST be created via a `Tracer`. +### TraceId and SpanId + +A `Span` has a two-part identifier associated with it, consisting of: + +- `TraceId` A valid trace identifier is a 16-byte array with at least one +non-zero byte. + +- `SpanId` A valid span identifier is an 8-byte array with at least one non-zero +byte. + +The TraceId is a globally unique identifier for the entire trace, while a SpanId is +a unique identifier within a trace. The concatenation can be considered the global +identifier of an individual `Span`. + +#### Retrieving the TraceId and SpanId + +The API MUST allow retrieving the `TraceId` and `SpanId` from a span in the following forms: + +* Hex - returns the lowercase [hex encoded](https://tools.ietf.org/html/rfc4648#section-8) +`TraceId` (result MUST be a 32-hex-character lowercase string) or `SpanId` +(result MUST be a 16-hex-character lowercase string). +* Binary - returns the binary representation of the `TraceId` (result MUST be a +16-byte array) `SpanId` (result MUST be a 8-byte array). + +The API should not expose details about how they are internally stored. + +### TraceFlags + +`TraceFlags` contain some additional propagated information about the span. Unlike TraceState values, +TraceFlags are present in all spans. The current version of the specification +only supports a single flag called [sampled](https://www.w3.org/TR/trace-context/#sampled-flag). + +### TraceState + +`TraceState` carries vendor-specific propagated data, represented as a list +of key-value pairs. TraceState allows multiple tracing +systems to participate in the same trace. It is fully described in the [W3C Trace Context +specification](https://www.w3.org/TR/trace-context/#tracestate-header). + +`TraceState` is represented by an immutable list of string key/value pairs and +formally defined by the [W3C Trace Context specification](https://www.w3.org/TR/trace-context/#tracestate-header). +Tracing API MUST provide at least the following operations on `TraceState`: + +* Return an empty `TraceState` +* Get value for a given key +* Create a copy with an added key/value pair +* Create a copy with an updated value for an existing key +* Create a copy with a removed key/value pair + +These operations MUST follow the rules described in the [W3C Trace Context specification](https://www.w3.org/TR/trace-context/#mutating-the-tracestate-field). +`TraceState` MUST at all times be valid according to rules specified in [W3C Trace Context specification](https://www.w3.org/TR/trace-context/#tracestate-header-field-values). +Every mutating operations MUST validate input parameters. +If invalid value is passed the operation MUST NOT return `TraceState` containing invalid data +and MUST follow the [general error handling guidelines](../error-handling.md) (e.g. it usually must not return null or throw an exception). + +Please note, since `TraceState` is fixed during span creation, it is not possible to update a span with a new `TraceState`. +Such changes then make sense only right before +[`Context` propagation](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/context/api-propagators.md) +or [telemetry data exporting](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk.md#span-exporter). +In both cases, `Propagators` and `SpanExporters` may create a modified `TraceState` copy before serializing it to the wire. + ### Span Creation There MUST NOT be any API for creating a `Span` other than with a [`Tracer`](#tracer). @@ -332,7 +322,7 @@ The API MUST accept the following parameters: - The parent `Context` or an indication that the new `Span` should be a root `Span`. The API MAY also have an option for implicitly using the current Context as parent as a default behavior. - This API MUST NOT accept a `Span` or `SpanContext` as parent, only a full `Context`. + This API MUST NOT accept a `Span` as parent, only a full `Context`. The semantic parent of the Span MUST be determined according to the rules described in [Determining the Parent Span from a Context](#determining-the-parent-span-from-a-context). @@ -362,19 +352,16 @@ Also, the child span MUST inherit all `TraceState` values of its parent by defau A `Span` is said to have a _remote parent_ if it is the child of a `Span` created in another process. Each propagators' deserialization must set -`IsRemote` to true on a parent `SpanContext` so `Span` creation knows if the +`IsRemote` to true on a parent `Span` so `Span` creation knows if the parent is remote. #### Determining the Parent Span from a Context When a new `Span` is created from a `Context`, the `Context` may contain a `Span` representing the currently active instance, and will be used as parent. +This may be a [Propagated Span](#propagated-span-creation) added by a `Propagator`. If there is no `Span` in the `Context`, the newly created `Span` will be a root span. -A `SpanContext` cannot be set as active in a `Context` directly, but through the use -of a [Propagated Span](#propagated-span-creation) wrapping it. -For example, a `Propagator` performing context extraction may need this. - #### Add Links During the `Span` creation user MUST have the ability to record links to other `Span`s. @@ -385,7 +372,7 @@ description](../overview.md#links-between-spans). A `Link` is defined by the following properties: -- (Required) `SpanContext` of the `Span` to link to. +- (Required) the `Span` to link to, or a `Context` containing the `Span` to link to, or the `TraceId`, `SpanId`, `TraceFlags`, and `TraceState` of the `Span` to link to - (Optional) One or more `Attribute`s as defined [here](../common/common.md#attributes). The `Link` SHOULD be an immutable type. @@ -399,16 +386,26 @@ Links SHOULD preserve the order in which they're set. ### Span operations -With the exception of the function to retrieve the `Span`'s `SpanContext` and -recording status, none of the below may be called after the `Span` is finished. +With the exception of the [accessors](#accessors) and recording status, none of the below may be called after +the `Span` is finished. -#### Get Context +#### Accessors -The Span interface MUST provide: +A `Span` must allow retrieving `TraceId` and `SpanId`, as described in +[Retrieving the TraceID and SpanID](#retrieving-the-traceid-and-spanid) and provide simple accessors for +`TraceFlags` and `TraceState`. + +#### IsValid + +An API called `IsValid` on a `Span`, that returns a boolean value, which is `true` if the Span has a +non-zero TraceID and a non-zero SpanID, MUST be provided. + +#### IsRemote -- An API that returns the `SpanContext` for the given `Span`. The returned value - may be used even after the `Span` is finished. The returned value MUST be the - same for the entire Span lifetime. This MAY be called `GetContext`. +An API called `IsRemote` on a `Span`, that returns a boolean value, which is `true` if the Span was +propagated from a remote parent, MUST be provided. +`IsRemote` must return `true` unless the `SpanId` for the `Span` was generated by this API implementation. +When `IsRemote` is `true`, `IsRecording` is always `false`. #### IsRecording @@ -421,8 +418,7 @@ There should be no parameter. This flag SHOULD be used to avoid expensive computations of a Span attributes or events in case when a Span is definitely not recorded. Note that any child span's recording is determined independently from the value of this flag -(typically based on the `sampled` flag of a `TraceFlag` on -[SpanContext](#spancontext)). +(typically based on the `sampled` flag in the `TraceFlags` of the [Span](#span)). This flag may be `true` despite the entire trace being sampled out. This allows to record and process information about the individual Span without @@ -578,17 +574,17 @@ calling of corresponding API. ### Propagated Span creation -The API MUST provide an operation for wrapping a `SpanContext` with an object -implementing the `Span` interface. This is done in order to expose a `SpanContext` -as a `Span` in operations such as in-process `Span` propagation. +The API MUST provide an operation for creating an object implementing the `Span` interface +provided `TraceId`, `SpanId`, `TraceFlags`, `TraceState`. This is done in order to expose it in operations such +as in-process `Span` propagation. If a new type is required for supporting this operation, it SHOULD be named `PropagatedSpan`. The behavior is defined as follows: -- `GetContext()` MUST return the wrapped `SpanContext`. - `IsRecording` MUST return `false` to signal that events, attributes and other elements are not being recorded, i.e. they are being dropped. +- `IsRemote` MUST return `true` to signal the `Span` corresponds to a remote span. The remaining functionality of `Span` MUST be defined as no-op operations. @@ -732,14 +728,14 @@ The API layer MAY include the following `Propagator`s: In general, in the absence of an installed SDK, the Trace API is a "no-op" API. This means that operations on a Tracer, or on Spans, should have no side effects and do nothing. However, there -is one important exception to this general rule, and that is related to propagation of a SpanContext. +is one important exception to this general rule, and that is related to propagation of a Span. The following cases must be considered when a new Span is requested to be created, especially in relation to the -requested parent SpanContext: +requested parent Span: -* A valid `SpanContext` is specified as the parent of the new `Span`: The API MUST treat this parent context as the -context for the newly created `Span`. This means that a `SpanContext` that has been provided by a configured `Propagator` -will be propagated through to any child span, but that no new `SpanContext`s will be created. -* No valid `SpanContext` is specified as the parent of the new `Span`: The API MUST create an non-valid +* A valid `Span` is specified as the parent of the new `Span`: The API MUST treat this parent context as the +context for the newly created `Span`. This means that a `Span` that has been provided by a configured `Propagator` +will be propagated through to any child span. +* No valid `Span` is specified as the parent of the new `Span`: The API MUST create an non-valid (both SpanID and TradeID are equivalent to being all zeros) `Span` for use by the API caller. This means that both the `TraceID` and the `SpanID` should be invalid. diff --git a/specification/trace/sdk.md b/specification/trace/sdk.md index 5da505e1e9b..285214e0dc8 100644 --- a/specification/trace/sdk.md +++ b/specification/trace/sdk.md @@ -30,8 +30,8 @@ The OpenTelemetry API has two properties responsible for the data collection: Processor](#span-processor) MUST receive only those spans which have this field set to `true`. However, [Span Exporter](#span-exporter) SHOULD NOT receive them unless the `Sampled` flag was also set. -* `Sampled` flag in `TraceFlags` on `SpanContext`. This flag is propagated via - the `SpanContext` to child Spans. For more details see the [W3C Trace Context +* `Sampled` flag in `TraceFlags` on `Span`. This flag is propagated via + the `Context` to child Spans. For more details see the [W3C Trace Context specification](https://www.w3.org/TR/trace-context/#sampled-flag). This flag indicates that the `Span` has been `sampled` and will be exported. [Span Exporters](#span-exporter) MUST receive those spans which have `Sampled` flag set to true and they SHOULD NOT receive the ones @@ -78,9 +78,9 @@ Returns the sampling Decision for a `Span` to be created. **Required arguments:** -* Parent `SpanContext`. May be invalid to indicate a root span. +* Parent `Span`. May be invalid to indicate a root span. * `TraceId` of the `Span` to be created. - If the parent `SpanContext` contains a valid `TraceId`, they MUST always match. + If the parent `Span` contains a valid `TraceId`, they MUST always match. * Name of the `Span` to be created. * `SpanKind` of the `Span` to be created. * Initial set of `Attributes` of the `Span` to be created. @@ -99,8 +99,7 @@ It produces an output called `SamplingResult` which contains: * `RECORD_AND_SAMPLE` - `IsRecording() == true` AND `Sampled` flag` MUST be set. * A set of span Attributes that will also be added to the `Span`. The returned object must be immutable (multiple calls may return different immutable objects). -* A `Tracestate` that will be associated with the `Span` through the new - `SpanContext`. +* A `Tracestate` that will be associated with the `Span`. If the sampler returns an empty `Tracestate` here, the `Tracestate` will be cleared, so samplers SHOULD normally return the passed-in `Tracestate` if they do not intend to change it. @@ -156,10 +155,10 @@ still be sampled and extra traces will be sampled on the backend only. * This is a composite sampler. `ParentBased` helps distinguished between the following cases: * No parent (root span). - * Remote parent (`SpanContext.IsRemote() == true`) with `SampledFlag` equals `true` - * Remote parent (`SpanContext.IsRemote() == true`) with `SampledFlag` equals `false` - * Local parent (`SpanContext.IsRemote() == false`) with `SampledFlag` equals `true` - * Local parent (`SpanContext.IsRemote() == false`) with `SampledFlag` equals `false` + * Remote parent (`Span.IsRemote() == true`) with `SampledFlag` equals `true` + * Remote parent (`Span.IsRemote() == true`) with `SampledFlag` equals `false` + * Local parent (`Span.IsRemote() == false`) with `SampledFlag` equals `true` + * Local parent (`Span.IsRemote() == false`) with `SampledFlag` equals `false` Required parameters: