mirror of
https://github.com/tokio-rs/tracing.git
synced 2025-09-28 13:31:52 +00:00
subscriber: add docs on registry span ID generation (#1453)
## Motivation Currently, `tracing-subscriber`'s `Registry` type doesn't document how span IDs are generated, or the uniqueness guarantees for span IDs. This can cause confusion for users trying to implement `Subscribe`rs and other code that interacts with the `Registry`'s generated span IDs. ## Solution This branch adds a new documentation section to the `Registry` docs describing how IDs are generated and when they are guaranteed to be unique. In particular, the new section explicitly states that the registry's IDs will not uniquely identify a span historically, because IDs may be reused when a span has closed, and that the registry's `tracing` span IDs should not be used as span IDs in a distributed tracing system. While I was working on these docs, I also fixed a link on adding subscribers to a registry that went to a specific method on `FmtSubscriber`, rather than to the more general docs on how subscribers are composed with collectors. Thanks to @Folyd for suggesting this docs improvement! Signed-off-by: Eliza Weisman <eliza@buoyant.io> Co-authored-by: David Barsky <me@davidbarsky.com>
This commit is contained in:
parent
504bb3ee9a
commit
4556cb3dc2
@ -23,26 +23,68 @@ use tracing_core::{
|
||||
///
|
||||
/// A `Registry` is a [`Subscriber`] around which multiple [`Layer`]s
|
||||
/// implementing various behaviors may be [added]. Unlike other types
|
||||
/// implementing `Subscriber` `Registry` does not actually record traces itself:
|
||||
/// instead, it collects and stores span data that is exposed to any `Layer`s
|
||||
/// implementing `Subscriber`, `Registry` does not actually record traces itself:
|
||||
/// instead, it collects and stores span data that is exposed to any [`Layer`]s
|
||||
/// wrapping it through implementations of the [`LookupSpan`] trait.
|
||||
/// The `Registry` is responsible for storing span metadata, recording
|
||||
/// relationships between spans, and tracking which spans are active and whicb
|
||||
/// are closed. In addition, it provides a mechanism for `Layer`s to store
|
||||
/// relationships between spans, and tracking which spans are active and which
|
||||
/// are closed. In addition, it provides a mechanism for [`Layer`]s to store
|
||||
/// user-defined per-span data, called [extensions], in the registry. This
|
||||
/// allows `Layer`-specific data to benefit from the `Registry`'s
|
||||
/// allows [`Layer`]-specific data to benefit from the `Registry`'s
|
||||
/// high-performance concurrent storage.
|
||||
///
|
||||
/// This registry is implemented using a [lock-free sharded slab][slab], and is
|
||||
/// highly optimized for concurrent access.
|
||||
///
|
||||
/// # Span ID Generation
|
||||
///
|
||||
/// Span IDs are not globally unique, but the registry ensures that
|
||||
/// no two currently active spans have the same ID within a process.
|
||||
///
|
||||
/// One of the primary responsibilities of the registry is to generate [span
|
||||
/// IDs]. Therefore, it's important for other code that interacts with the
|
||||
/// registry, such as [`Layer`]s, to understand the guarantees of the
|
||||
/// span IDs that are generated.
|
||||
///
|
||||
/// The registry's span IDs are guaranteed to be unique **at a given point
|
||||
/// in time**. This means that an active span will never be assigned the
|
||||
/// same ID as another **currently active** span. However, the registry
|
||||
/// **will** eventually reuse the IDs of [closed] spans, although an ID
|
||||
/// will never be reassigned immediately after a span has closed.
|
||||
///
|
||||
/// Spans are not [considered closed] by the `Registry` until *every*
|
||||
/// [`Span`] reference with that ID has been dropped.
|
||||
///
|
||||
/// Thus: span IDs generated by the registry should be considered unique
|
||||
/// only at a given point in time, and only relative to other spans
|
||||
/// generated by the same process. Two spans with the same ID will not exist
|
||||
/// in the same process concurrently. However, if historical span data is
|
||||
/// being stored, the same ID may occur for multiple spans times in that
|
||||
/// data. If spans must be uniquely identified in historical data, the user
|
||||
/// code storing this data must assign its own unique identifiers to those
|
||||
/// spans. A counter is generally sufficient for this.
|
||||
///
|
||||
/// Similarly, span IDs generated by the registry are not unique outside of
|
||||
/// a given process. Distributed tracing systems may require identifiers
|
||||
/// that are unique across multiple processes on multiple machines (for
|
||||
/// example, [OpenTelemetry's `SpanId`s and `TraceId`s][ot]). `tracing` span
|
||||
/// IDs generated by the registry should **not** be used for this purpose.
|
||||
/// Instead, code which integrates with a distributed tracing system should
|
||||
/// generate and propagate its own IDs according to the rules specified by
|
||||
/// the distributed tracing system. These IDs can be associated with
|
||||
/// `tracing` spans using [fields] and/or [stored span data].
|
||||
///
|
||||
/// [span IDs]: https://docs.rs/tracing-core/latest/tracing_core/span/struct.Id.html
|
||||
/// [slab]: https://docs.rs/crate/sharded-slab/
|
||||
/// [`Subscriber`]:
|
||||
/// https://docs.rs/crate/tracing-core/latest/tracing_core/subscriber/trait.Subscriber.html
|
||||
/// [`Layer`]: ../trait.Layer.html
|
||||
/// [added]: ../trait.Layer.html#method.with_subscriber
|
||||
/// [`LookupSpan`]: trait.LookupSpan.html
|
||||
/// [extensions]: extensions/index.html
|
||||
/// [`Layer`]: crate::Layer
|
||||
/// [added]: crate::layer::Layer#composing-layers
|
||||
/// [extensions]: super::Extensions
|
||||
/// [closed]: https://docs.rs/tracing/latest/tracing/span/index.html#closing-spans
|
||||
/// [considered closed]: https://docs.rs/tracing-core/latest/tracing_core/subscriber/trait.Subscriber.html#method.try_close
|
||||
/// [`Span`]: https://docs.rs/tracing/latest/tracing/span/struct.Span.html
|
||||
/// [ot]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#spancontext
|
||||
/// [fields]: https://docs.rs/tracing-core/latest/tracing-core/field/index.html
|
||||
/// [stored span data]: crate::registry::SpanData::extensions_mut
|
||||
#[cfg(feature = "registry")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "registry")))]
|
||||
#[derive(Debug)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user