Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken trace example #1690

Open
cijothomas opened this issue Apr 30, 2024 · 1 comment
Open

Broken trace example #1690

cijothomas opened this issue Apr 30, 2024 · 1 comment

Comments

@cijothomas
Copy link
Member

This issue is simple example to showcase broken traces when intermixing OTel Tracing API and Tokio-tracing API.

Cargo.toml

[package]
name = "otel-tracing-interop"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
opentelemetry = "0.22.0"
opentelemetry-stdout = { version = "0.3.0", features = ["trace"] }
opentelemetry_sdk = "0.22.1"
serde_json = "1.0.116"
tracing = "0.1.40"
tracing-opentelemetry = "0.23.0"
tracing-subscriber = "0.3.18"

main.rs

use opentelemetry::{
    trace::{Span, Tracer, TracerProvider as _},
    KeyValue,
};

use opentelemetry_sdk::{
    resource,
    trace::{config, Config, TracerProvider},
    Resource,
};
use opentelemetry_stdout::SpanExporterBuilder;
use tracing::span;
use tracing_subscriber::{layer::SubscriberExt, Registry};

fn main() {
    println!("Hello, world!");
    let stdout_exporter = SpanExporterBuilder::default()
        .with_encoder(|writer, data| {
            serde_json::to_writer_pretty(writer, &data).unwrap();
            Ok(())
        })
        .build();
    let provider = TracerProvider::builder()
        .with_config(Config::default().with_resource(Resource::new(vec![])))
        .with_simple_exporter(stdout_exporter)
        .build();
    let tracer = provider.tracer("tracing-opentelemetry");
    let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
    let subscriber = Registry::default().with(telemetry);

    tracing::subscriber::with_default(subscriber, || {
        let tracer = provider.tracer("otel-tracing");

        // this is the root span created using tokio tracing api
        let root = span!(tracing::Level::TRACE, "tokio-tracing-span-parent");
        let _enter = root.enter();

        // this is a child span created using tokio tracing api
        // this correctly parented to the root span
        let child = span!(tracing::Level::TRACE, "tokio-tracing-span-child");
        let _enter_child = child.enter();

        // this is another child, created using otel tracing api
        // but this is *NOT* parented to the above spans
        // demonstrating broken traces when mixing and matching tracing and opentelemetry apis
        let mut span = tracer.span_builder("otel-tracing-span").start(&tracer);
        span.end();
    });
}
@lalitb
Copy link
Member

lalitb commented May 3, 2024

The problem here is that if the Span is active in the tracing context, tracing-opentelemetry willn't make it active in the thread_local otel context. So any span created thereafter using otel API will have no information of the span created and made active by tracing API. So in the current state, the Otel tracing API will need to read the active span from the tracing context (along with the otel context as done already) to figure out the parent. The issue is somewhat similar to logging as described here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants