mirror of
https://github.com/tokio-rs/tracing.git
synced 2025-10-02 15:24:47 +00:00

## Motivation Support the latest OpenTelemetry specification. ## Solution Update `opentelemetry` to the latest `0.14.x` release. Despite breaking changes upstream, no additional public API or behavioral changes are necessary in `tracing-opentelemetry`, but simplifications in the propagation of span information have removed the need for the current internal `CompatSpan` and custom parent context construction. Performance has improved by ~30% on current benchmarks.
102 lines
3.6 KiB
Rust
102 lines
3.6 KiB
Rust
use crate::layer::WithContext;
|
|
use opentelemetry::Context;
|
|
|
|
/// Utility functions to allow tracing [`Span`]s to accept and return
|
|
/// [OpenTelemetry] [`Context`]s.
|
|
///
|
|
/// [`Span`]: https://docs.rs/tracing/latest/tracing/struct.Span.html
|
|
/// [OpenTelemetry]: https://opentelemetry.io
|
|
/// [`Context`]: opentelemetry::Context
|
|
pub trait OpenTelemetrySpanExt {
|
|
/// Associates `self` with a given OpenTelemetry trace, using the provided
|
|
/// parent [`Context`].
|
|
///
|
|
/// [`Context`]: opentelemetry::Context
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// use opentelemetry::{propagation::TextMapPropagator, trace::TraceContextExt};
|
|
/// use opentelemetry::sdk::propagation::TraceContextPropagator;
|
|
/// use tracing_opentelemetry::OpenTelemetrySpanExt;
|
|
/// use std::collections::HashMap;
|
|
/// use tracing::Span;
|
|
///
|
|
/// // Example carrier, could be a framework header map that impls otel's `Extract`.
|
|
/// let mut carrier = HashMap::new();
|
|
///
|
|
/// // Propagator can be swapped with b3 propagator, jaeger propagator, etc.
|
|
/// let propagator = TraceContextPropagator::new();
|
|
///
|
|
/// // Extract otel parent context via the chosen propagator
|
|
/// let parent_context = propagator.extract(&carrier);
|
|
///
|
|
/// // Generate a tracing span as usual
|
|
/// let app_root = tracing::span!(tracing::Level::INFO, "app_start");
|
|
///
|
|
/// // Assign parent trace from external context
|
|
/// app_root.set_parent(parent_context.clone());
|
|
///
|
|
/// // Or if the current span has been created elsewhere:
|
|
/// Span::current().set_parent(parent_context);
|
|
/// ```
|
|
fn set_parent(&self, cx: Context);
|
|
|
|
/// Extracts an OpenTelemetry [`Context`] from `self`.
|
|
///
|
|
/// [`Context`]: opentelemetry::Context
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// use opentelemetry::Context;
|
|
/// use tracing_opentelemetry::OpenTelemetrySpanExt;
|
|
/// use tracing::Span;
|
|
///
|
|
/// fn make_request(cx: Context) {
|
|
/// // perform external request after injecting context
|
|
/// // e.g. if the request's headers impl `opentelemetry::propagation::Injector`
|
|
/// // then `propagator.inject_context(cx, request.headers_mut())`
|
|
/// }
|
|
///
|
|
/// // Generate a tracing span as usual
|
|
/// let app_root = tracing::span!(tracing::Level::INFO, "app_start");
|
|
///
|
|
/// // To include tracing context in client requests from _this_ app,
|
|
/// // extract the current OpenTelemetry context.
|
|
/// make_request(app_root.context());
|
|
///
|
|
/// // Or if the current span has been created elsewhere:
|
|
/// make_request(Span::current().context())
|
|
/// ```
|
|
fn context(&self) -> Context;
|
|
}
|
|
|
|
impl OpenTelemetrySpanExt for tracing::Span {
|
|
fn set_parent(&self, cx: Context) {
|
|
let mut cx = Some(cx);
|
|
self.with_subscriber(move |(id, subscriber)| {
|
|
if let Some(get_context) = subscriber.downcast_ref::<WithContext>() {
|
|
get_context.with_context(subscriber, id, move |builder, _tracer| {
|
|
if let Some(cx) = cx.take() {
|
|
builder.parent_context = cx;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
fn context(&self) -> Context {
|
|
let mut cx = None;
|
|
self.with_subscriber(|(id, subscriber)| {
|
|
if let Some(get_context) = subscriber.downcast_ref::<WithContext>() {
|
|
get_context.with_context(subscriber, id, |builder, tracer| {
|
|
cx = Some(tracer.sampled_context(builder));
|
|
})
|
|
}
|
|
});
|
|
|
|
cx.unwrap_or_default()
|
|
}
|
|
}
|