diff --git a/CHANGELOG.md b/CHANGELOG.md index a9bfdfb6b90..1962da5af57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -136,6 +136,8 @@ Updates: - SDK: Specify known values, as well as basic error handling for OTEL_PROPAGATORS. ([#962](https://github.com/open-telemetry/opentelemetry-specification/pull/962)) ([#995](https://github.com/open-telemetry/opentelemetry-specification/pull/995)) +- SDK: Specify when to generate new IDs with sampling + ([#998](https://github.com/open-telemetry/opentelemetry-specification/pull/998)) - Remove custom header name for Baggage, use official header ([#993](https://github.com/open-telemetry/opentelemetry-specification/pull/993)) - Trace API: Clarifications for `Span.End`, e.g. IsRecording becomes false after End diff --git a/spec-compliance-matrix.md b/spec-compliance-matrix.md index dc9b5534fc1..ab7a564182f 100644 --- a/spec-compliance-matrix.md +++ b/spec-compliance-matrix.md @@ -68,6 +68,7 @@ status of the feature is not known. |[Sampling](specification/trace/sdk.md#sampling)| |Allow samplers to modify tracestate | | + | | [-](https://github.com/open-telemetry/opentelemetry-python/issues/1220) | | + | | + | | | |ShouldSample gets full parent Context | | + | + | + | | + | | | | | +|[Span/Trace ID creation wrt. sampling is compliant](specification/trace/sdk.md#sdk-span-creation) | | | | | | | | | | | ## Baggage diff --git a/specification/trace/sdk.md b/specification/trace/sdk.md index 4f69378fcb3..830e422044c 100644 --- a/specification/trace/sdk.md +++ b/specification/trace/sdk.md @@ -61,11 +61,28 @@ The following table summarizes the expected behavior for each combination of The SDK defines the interface [`Sampler`](#sampler) as well as a set of [built-in samplers](#built-in-samplers) and associates a `Sampler` with each [`TracerProvider`]. -When asked to create a Span, the SDK MUST query the `Sampler`'s [`ShouldSample`](#shouldsample) method before actually creating the span, and act accordingly: -see description of [`ShouldSample`'s](#shouldsample) return value below for how to set `IsRecording` and `Sampled` on the Span, -and the [table above](#recording-sampled-reaction-table) on whether to pass the `Span` to `SpanProcessor`s. -A non-recording span MAY be implemented using the same mechanism as when a `Span` is created with no API-implementation installed -(sometimes called a `NoOpSpan` or `DefaultSpan`). +### SDK Span creation + +When asked to create a Span, the SDK MUST act as if doing the following in order: + +1. If there is a valid parent trace ID, use it. Otherwise generate a new trace ID + (note: this must be done before calling `ShouldSample`, because it expects + a valid trace ID as input). +2. Query the `Sampler`'s [`ShouldSample`](#shouldsample) method + (Note that the [built-in `ParentBasedSampler`](#parentbased) can be used to + use the sampling decision of the parent, + translating a set SampledFlag to RECORD and an unset one to DROP). +3. If the decision is `DROP` and there is a valid parent span ID, reuse it as the new `Span`'s span ID. + Otherwise (if the decision is not `DROP` or there was no valid parent span ID) + a new span ID MUST be generated. +4. Create a span depending on the decision returned by `ShouldSample`: + see description of [`ShouldSample`'s](#shouldsample) return value below + for how to set `IsRecording` and `Sampled` on the Span, + and the [table above](#recording-sampled-reaction-table) on whether + to pass the `Span` to `SpanProcessor`s. + A non-recording span MAY be implemented using the same mechanism as when a + `Span` is created with no API-implementation installed or as described in + [wrapping a SpanContext in a Span](api.md#wrapping-a-spancontext-in-a-span). ### Sampler