Skip to content

Commit

Permalink
sdk: Update sampling documentation
Browse files Browse the repository at this point in the history
* Move Sampling header into `Sampler`
* Enrich classes to have links in tracing module

Relates #800

Signed-off-by: Harold Dost <github@hdost.com>
  • Loading branch information
hdost committed Jul 7, 2022
1 parent c13a11e commit 2e5a6c3
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 57 deletions.
6 changes: 3 additions & 3 deletions opentelemetry-sdk/src/trace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
//!
//! The tracing SDK consist of a few main structs:
//!
//! * The `Tracer` struct which performs all tracing operations.
//! * The `Span` struct with is a mutable object storing information about the
//! * The [`Tracer`] struct which performs all tracing operations.
//! * The [`Span`] struct with is a mutable object storing information about the
//! current operation execution.
//! * The `TracerProvider` struct which configures and produces `Tracer`s.
//! * The [`TracerProvider`] struct which configures and produces [`Tracer`]s.
mod config;
mod evicted_hash_map;
mod evicted_queue;
Expand Down
20 changes: 10 additions & 10 deletions opentelemetry-sdk/src/trace/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
//!
//! ## Tracer Creation
//!
//! New `Tracer` instances are always created through a `TracerProvider`.
//! New [`Tracer`] instances are always created through a [`TracerProvider`].
//!
//! All configuration objects and extension points (span processors,
//! propagators) are provided by the `TracerProvider`. `Tracer` instances do
//! not duplicate this data to avoid that different `Tracer` instances
//! of the `TracerProvider` have different versions of these data.
//! propagators) are provided by the [`TracerProvider`]. [`Tracer`] instances do
//! not duplicate this data to avoid that different [`Tracer`] instances
//! of the [`TracerProvider`] have different versions of these data.
use crate::trace::{runtime::TraceRuntime, BatchSpanProcessor, SimpleSpanProcessor, Tracer};
use crate::{export::trace::SpanExporter, trace::SpanProcessor};
use crate::{InstrumentationLibrary, Resource};
Expand Down Expand Up @@ -37,7 +37,7 @@ impl Drop for TracerProviderInner {
}
}

/// Creator and registry of named `Tracer` instances.
/// Creator and registry of named [`Tracer`] instances.
#[derive(Clone, Debug)]
pub struct TracerProvider {
inner: Arc<TracerProviderInner>,
Expand All @@ -55,7 +55,7 @@ impl TracerProvider {
TracerProvider { inner }
}

/// Create a new `TracerProvider` builder.
/// Create a new [`TracerProvider`] builder.
pub fn builder() -> Builder {
Builder::default()
}
Expand Down Expand Up @@ -159,7 +159,7 @@ impl Builder {
Builder { processors, ..self }
}

/// The `SpanExporter` setup using a default `BatchSpanProcessor` that this provider should use.
/// The [`SpanExporter`] setup using a default [`BatchSpanProcessor`] that this provider should use.
pub fn with_batch_exporter<T: SpanExporter + 'static, R: TraceRuntime>(
self,
exporter: T,
Expand All @@ -169,15 +169,15 @@ impl Builder {
self.with_span_processor(batch)
}

/// The `SpanProcessor` that this provider should use.
/// The [`SpanProcessor`] that this provider should use.
pub fn with_span_processor<T: SpanProcessor + 'static>(self, processor: T) -> Self {
let mut processors = self.processors;
processors.push(Box::new(processor));

Builder { processors, ..self }
}

/// The sdk `Config` that this provider will use.
/// The sdk [`crate::trace::Config`] that this provider will use.
pub fn with_config(self, config: crate::trace::Config) -> Self {
Builder { config, ..self }
}
Expand All @@ -186,7 +186,7 @@ impl Builder {
pub fn build(self) -> TracerProvider {
let mut config = self.config;

// Standard config will contain an owned `Resource` (either sdk default or use supplied)
// Standard config will contain an owned [`Resource`] (either sdk default or use supplied)
// we can optimize the common case with a static ref to avoid cloning the underlying
// resource data for each span.
//
Expand Down
108 changes: 64 additions & 44 deletions opentelemetry-sdk/src/trace/sampler.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,3 @@
//! # OpenTelemetry ShouldSample Interface
//!
//! ## Sampling
//!
//! Sampling is a mechanism to control the noise and overhead introduced by
//! OpenTelemetry by reducing the number of samples of traces collected and
//! sent to the backend.
//!
//! Sampling may be implemented on different stages of a trace collection.
//! OpenTelemetry SDK defines a `ShouldSample` interface that can be used at
//! instrumentation points by libraries to check the sampling `SamplingDecision`
//! early and optimize the amount of telemetry that needs to be collected.
//!
//! All other sampling algorithms may be implemented on SDK layer in exporters,
//! or even out of process in Agent or Collector.
//!
//! The OpenTelemetry API has two properties responsible for the data collection:
//!
//! * `is_recording` method on a `Span`. If `true` the current `Span` records
//! tracing events (attributes, events, status, etc.), otherwise all tracing
//! events are dropped. Users can use this property to determine if expensive
//! trace events can be avoided. `SpanProcessor`s will receive
//! all spans with this flag set. However, `SpanExporter`s will
//! not receive them unless the `Sampled` flag was set.
//! * `Sampled` flag in `trace_flags` on `SpanContext`. This flag is propagated
//! via the `SpanContext` to child Spans. For more details see the [W3C
//! specification](https://w3c.github.io/trace-context/). This flag indicates
//! that the `Span` has been `sampled` and will be exported. `SpanProcessor`s
//! and `SpanExporter`s will receive spans with the `Sampled` flag set for
//! processing.
//!
//! The flag combination `Sampled == false` and `is_recording` == true` means
//! that the current `Span` does record information, but most likely the child
//! `Span` will not.
//!
//! The flag combination `Sampled == true` and `is_recording == false` could
//! cause gaps in the distributed trace, and because of this OpenTelemetry API
//! MUST NOT allow this combination.

use crate::InstrumentationLibrary;
use opentelemetry_api::trace::OrderMap;
use opentelemetry_api::{
Expand All @@ -57,11 +18,63 @@ pub use jaeger_remote::JaegerRemoteSamplerBuilder;
#[cfg(feature = "jaeger_remote_sampler")]
use opentelemetry_http::HttpClient;

/// The `ShouldSample` interface allows implementations to provide samplers
/// which will return a sampling `SamplingResult` based on information that
/// is typically available just before the `Span` was created.
/// The [`ShouldSample`] interface allows implementations to provide samplers
/// which will return a sampling [`SamplingResult`] based on information that
/// is typically available just before the [`Span`] was created.
///
/// # Sampling
///
/// Sampling is a mechanism to control the noise and overhead introduced by
/// OpenTelemetry by reducing the number of samples of traces collected and
/// sent to the backend.
///
/// Sampling may be implemented on different stages of a trace collection.
/// [OpenTelemetry SDK] defines a [`ShouldSample`] interface that can be used at
/// instrumentation points by libraries to check the sampling [`SamplingDecision`]
/// early and optimize the amount of telemetry that needs to be collected.
///
/// All other sampling algorithms may be implemented on SDK layer in exporters,
/// or even out of process in Agent or Collector.
///
/// The OpenTelemetry API has two properties responsible for the data collection:
///
/// * [`Span::is_recording()`]. If `true` the current [`Span`] records
/// tracing events (attributes, events, status, etc.), otherwise all tracing
/// events are dropped. Users can use this property to determine if expensive
/// trace events can be avoided. [`SpanProcessor`]s will receive
/// all spans with this flag set. However, [`SpanExporter`]s will
/// not receive them unless the `Sampled` flag was set.
/// * `Sampled` flag in [`SpanContext::trace_flags()`]. This flag is propagated
/// via the [`SpanContext`] to child Spans. For more details see the [W3C
/// specification](https://w3c.github.io/trace-context/). This flag indicates
/// that the [`Span`] has been `sampled` and will be exported. [`SpanProcessor`]s
/// and [`SpanExporter`]s will receive spans with the `Sampled` flag set for
/// processing.
///
/// The flag combination `Sampled == false` and `is_recording` == true` means
/// that the current `Span` does record information, but most likely the child
/// `Span` will not.
///
/// The flag combination `Sampled == true` and `is_recording == false` could
/// cause gaps in the distributed trace, and because of this OpenTelemetry API
/// MUST NOT allow this combination.
///
/// [OpenTelemetry SDK]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#sampling
/// [`SpanContext`]: opentelemetry_api::trace::SpanContext
/// [`SpanContext::trace_flags()`]: opentelemetry_api::trace::SpanContext#method.trace_flags
/// [`SpanExporter`]: crate::export::trace::SpanExporter
/// [`SpanProcessor`]: crate::trace::SpanProcessor
/// [`Span`]: opentelemetry_api::trace::Span
/// [`Span::is_recording()`]: opentelemetry_api::trace::Span#tymethod.is_recording
pub trait ShouldSample: Send + Sync + std::fmt::Debug {
/// Returns the `SamplingDecision` for a `Span` to be created.
/// Returns the [`SamplingDecision`] for a [`Span`] to be created.
///
/// The [`should_sample`] function can use any of the information provided to it in order to
/// make a decision about whether or not a [`Span`] should or should not be sampled. However,
/// there are performance implications on the creation of a span
///
/// [`Span`]: opentelemetry_api::trace::Span
/// [`should_sample`]: ShouldSample::should_sample
#[allow(clippy::too_many_arguments)]
fn should_sample(
&self,
Expand All @@ -75,7 +88,12 @@ pub trait ShouldSample: Send + Sync + std::fmt::Debug {
) -> SamplingResult;
}

/// Build in samplers.
/// Default Sampling options
///
/// The [built-in samplers] allow for simple decisions. For more complex scenarios consider
/// implementing your own sampler using [`ShouldSample`] trait.
///
/// [built-in samplers]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk.md#built-in-samplers
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum Sampler {
Expand All @@ -88,6 +106,8 @@ pub enum Sampler {
/// Sample a given fraction of traces. Fractions >= 1 will always sample. If the parent span is
/// sampled, then it's child spans will automatically be sampled. Fractions < 0 are treated as
/// zero, but spans may still be sampled if their parent is.
/// *Note:* If this is used then all Spans in a trace will become sampled assuming that the
/// first span is sampled as it is based on the `trace_id` not the `span_id`
TraceIdRatioBased(f64),
/// Jaeger remote sampler supports any remote service that implemented the jaeger remote sampler protocol.
/// The proto definition can be found [here](https://github.com/jaegertracing/jaeger-idl/blob/main/proto/api_v2/sampling.proto)
Expand Down

0 comments on commit 2e5a6c3

Please sign in to comment.