Skip to content

Commit c4fe96a

Browse files
feat: OpenTelemetry context activation (#202)
An OpenTelemetry `Context` that mirrors the active `tracing` `Span` is now active on the executing thread while in a `tracing` `Span`. Having _proper_ OpenTelemetry context activation will not only make interoperability easier for users of the OpenTelemetry API, but will also open up the possibility for simpler log/trace/baggage correlation and in the future profiling/trace correlation among other things. ## Motivation The aim is to provide users of the OpenTelemetry API a more seamless and consistent experience. One such thing is that calling the OpenTelemetry API `Context::current()` did not give you a `Context` that contained an OpenTelemetry `Span` that represented the current `tracing` `Span`. Another thing is propagation of `Baggage` or user defined types that were not picked up either. A lot of effort has been put into making the existing `OpenTelemetrySpanExt` API work the same way to maintain maximum backwards compatibility and to avoid fragmentation by building a separate OpenTelemetry and Tokio Tracing bridge. [Long discussion](open-telemetry/opentelemetry-rust#1571) about OpenTelemetry and Tokio Tracing interoperability, and an [issue](open-telemetry/opentelemetry-rust#2420) specifically discussing this POC. ## Solution This solution adds a new feature `activate_context` that will activate/deactivate an OpenTelemetry `Context` that mirrors the current `tracing` `Span`. This feature is currently on by default, but can be turned off to avoid any performance overhead incurred by the context activation and bookkeeping. The second big change is that the OpenTelemetry `SpanBuilder` is lazily consumed and a real OpenTelemetry `Span` is created when necessary, so there is no longer any need for the `PreSampledTracer` and the special code in OpenTelemetry that it relies on. This has some implications, like you can no longer set the `parent_context` after you have entered a `Span` or called the `context` method on the `Span`. Benchmark numbers are available in this [comment](open-telemetry/opentelemetry-rust#2420 (comment)), and when the `activate_context` feature is turned off, the performance stays the same. (There has been one more optimization since the last run there, fixing the regression in the `many_events` benchmarks) --------- Co-authored-by: Scott Gerring <[email protected]>
1 parent 764cd73 commit c4fe96a

File tree

11 files changed

+1350
-648
lines changed

11 files changed

+1350
-648
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ Cargo.lock
5050

5151

5252
# End of https://www.gitignore.io/api/rust,macos,visualstudiocode
53+
.cursor

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ tracing-subscriber = { version = "0.3.0", default-features = false, features = [
2929
tracing-log = { version = "0.2.0", default-features = false, optional = true }
3030
rustversion = "1.0.9"
3131
smallvec = { version = "1.0", optional = true }
32+
thiserror = { version = "2", default-features = false }
3233

3334
# Fix minimal-versions
3435
lazy_static = { version = "1.0.2", optional = true }
@@ -37,7 +38,7 @@ lazy_static = { version = "1.0.2", optional = true }
3738
async-trait = "0.1.56"
3839
criterion = { version = "0.5.1", default-features = false, features = ["html_reports"] }
3940
opentelemetry = { version = "0.30.0", features = ["trace", "metrics"] }
40-
opentelemetry_sdk = { version = "0.30.0", default-features = false, features = ["trace", "rt-tokio", "experimental_metrics_custom_reader"] }
41+
opentelemetry_sdk = { version = "0.30.0", default-features = false, features = ["trace", "rt-tokio", "experimental_metrics_custom_reader", "testing"] }
4142
opentelemetry-stdout = { version = "0.30.0", features = ["trace", "metrics"] }
4243
opentelemetry-otlp = { version = "0.30.0", features = ["metrics", "grpc-tonic"] }
4344
opentelemetry-semantic-conventions = { version = "0.30.0", features = ["semconv_experimental"] }

benches/trace.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,7 @@ where
264264
let span = ctx.span(&id).expect("Span not found, this is a bug");
265265
let mut extensions = span.extensions_mut();
266266

267-
if let Some(builder) = extensions.remove::<SpanBuilder>() {
268-
builder.with_end_time(SystemTime::now());
269-
}
267+
extensions.remove::<SpanBuilder>();
270268
}
271269
}
272270

examples/opentelemetry-remote-context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn main() {
3737
let app_root = span!(tracing::Level::INFO, "app_start");
3838

3939
// Assign parent trace from external context
40-
app_root.set_parent(parent_context);
40+
let _ = app_root.set_parent(parent_context);
4141

4242
// To include tracing context in client requests from _this_ app,
4343
// use `context` to extract the current OpenTelemetry context.

0 commit comments

Comments
 (0)