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

set_global_default does not seem to work #3217

Open
joseph-henry opened this issue Feb 12, 2025 · 2 comments
Open

set_global_default does not seem to work #3217

joseph-henry opened this issue Feb 12, 2025 · 2 comments

Comments

@joseph-henry
Copy link

Bug Report

Version

│   └── tracing v0.1.41
│       ├── tracing-attributes v0.1.28 (proc-macro)
│       └── tracing-core v0.1.33
│   │   │   └── tracing v0.1.41 (*)
│   │       │   └── tracing v0.1.41 (*)
│   │       │   │   └── tracing v0.1.41 (*)
│   │       │   └── tracing v0.1.41 (*)
│   │       └── tracing v0.1.41 (*)
│   └── tracing v0.1.41 (*)
├── tracing v0.1.41 (*)
├── tracing-opentelemetry v0.28.0
│   ├── tracing v0.1.41 (*)
│   ├── tracing-core v0.1.33 (*)
│   ├── tracing-log v0.2.0
│   │   └── tracing-core v0.1.33 (*)
│   └── tracing-subscriber v0.3.19
│       └── tracing-core v0.1.33 (*)
└── tracing-subscriber v0.3.19 (*)

Platform

Linux 6.9.3-76060903-generic #202405300957~1738770968~22.04~d5f7c84 SMP PREEMPT_DYNAMIC Wed F x86_64 x86_64 x86_64 GNU/Linux

Crates

I'm not yet sure where the failure is. I suspect it's in tracing but here's my Cargo.toml:

tracing = { version = "0.1.35", default-features = false, features = ["std", "attributes"] }
opentelemetry = { version = "0.27.0", features = ["trace", "metrics"] }
opentelemetry_sdk = { version = "0.27.0", default-features = false, features = ["trace", "rt-tokio"] }
opentelemetry-stdout = { version = "0.27.0", features = ["trace", "metrics"] }
tracing-subscriber = { version = "0.3.0", default-features = false, features = ["registry", "std", "fmt"] }
tracing-opentelemetry = "0.28.0"
opentelemetry-otlp = "0.27.0"
opentelemetry-semantic-conventions = "0.27.0" # for service name
tokio = { version = "1.41.1", features = ["full"] 

Description

Hello. I'm trying to set the default subscriber for my entire program using set_global_default but am not getting the result that I expect. I can use set_default successfully, and I can use .with_default in a closure successfully.

When I use method 1 or 2 in the code below, my tracing events are sent to my collector, but when I use method 1 (set_global_default) nothing is sent to my collector and no error is emitted when I check its state. Any help would be greatly appreciated. Thanks!

use opentelemetry::trace::TracerProvider as _;
use opentelemetry::KeyValue;
use opentelemetry_otlp::WithExportConfig;
use opentelemetry_sdk::trace::TracerProvider;
use opentelemetry_sdk::{runtime, Resource};
use opentelemetry_semantic_conventions::resource::SERVICE_NAME;
use tracing::{error, info, span, trace};
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::Registry;

#[tokio::main]
async fn main() {
    let exporter = opentelemetry_otlp::SpanExporter::builder()
        .with_tonic()
        .with_endpoint("http://localhost:4317")
        .build()
        .unwrap();

    let provider = TracerProvider::builder()
        .with_batch_exporter(exporter, runtime::Tokio)
        .with_resource(Resource::new(vec![KeyValue::new(
            SERVICE_NAME,
            "test-service",
        )]))
        .build();

    let tracer = provider.tracer("global_tracer");
    let telemetry = tracing_opentelemetry::layer().with_tracer(tracer.clone());
    let subscriber = Registry::default().with(telemetry);

    // Method 1: Set subscribe as global default (Doesn't work)
    tracing::subscriber::set_global_default(subscriber).expect("setting default subscriber failed");
    let root = span!(tracing::Level::TRACE, "app_start", work_units = 2);
    let _enter = root.enter();
    trace!("This is a trace event.");
    error!("This is an error event.");
    info!("This is an info event.");

    // Method 2: Set subscriber as default (Works)
    /*
    let _guard = tracing::subscriber::set_default(subscriber);
    let root = span!(tracing::Level::TRACE, "app_start", work_units = 2);
    let _enter = root.enter();
    trace!("This is a trace event.");
    error!("This is an error event.");
    info!("This is an info event.");
    */

    // Method 3: Trace executed code inside of a closure (Works)
    /*
    tracing::subscriber::with_default(subscriber, || {
        // Spans will be sent to the configured OpenTelemetry exporter
        let root = span!(tracing::Level::TRACE, "app_start", work_units = 2);
        let _enter = root.enter();
        trace!("This is a trace event");
    });
    */

    let current_span = tracing::Span::current();
    println!("Current span: {:?}", current_span);
}

Thanks!

@joseph-henry
Copy link
Author

It seems like this example although different from what I'm trying to do does demonstrate that set_global_default can work, but why would the subscriber make any difference here? The subscriber clearly works in my original example when I use set_default.

use tracing::{info, Level};
use tracing_subscriber::FmtSubscriber;

fn main() {
    // a builder for `FmtSubscriber`.
    let subscriber = FmtSubscriber::builder()
        // all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.)
        // will be written to stdout.
        .with_max_level(Level::TRACE)
        // completes the builder.
        .finish();

    tracing::subscriber::set_global_default(subscriber)
        .expect("setting default subscriber failed");

    let number_of_yaks = 3;
    // this creates a new event, outside of any spans.
    info!(number_of_yaks, "preparing to shave yaks");

    let number_shaved = yak_shave::shave_all(number_of_yaks);
    info!(
        all_yaks_shaved = number_shaved == number_of_yaks,
        "yak shaving completed."
    );
}

@kaffarell
Copy link
Contributor

kaffarell commented Feb 20, 2025

Just skimming quickly over open-telemetry/opentelemetry-rust#1961 it seems that this is known and expected.
set_global_default has been removed from any examples but maybe it would be nice to include a big comment on top of the tracing_opentelemetry::layer::OpenTelemetryLayer struct.

In any case, this is not a tracing issue.

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