Panic with Zipkin

I am trying to get Zipkin tracing working in a simple example, but get this panic with the following code. What am I missing here?

Error
Cannot drop a runtime in a context where blocking is not allowed. This happens when a runtime is dropped from within an asynchronous context.

Code

use axum::{routing::get, Json, Router};
use serde::Serialize;
use std::net::SocketAddr;
use tracing::{info, instrument};
use tracing_subscriber::{layer::SubscriberExt, Registry};

#[derive(Serialize)]
struct ApiResponse {
    message: String,
    status: u16,
}

#[tokio::main]
async fn main() {
    init_tracing();

    let app = Router::new()
        .route("/", get(root_handler))
        .route("/hello", get(hello_handler));

    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    info!("Listening on http://{}", addr);

    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

#[instrument]
async fn root_handler() -> Json<ApiResponse> {
    Json(ApiResponse {
        message: "Welcome to the Rust API!".to_string(),
        status: 200,
    })
}

#[instrument]
async fn hello_handler() -> Json<ApiResponse> {
    Json(ApiResponse {
        message: "Hello, world!".to_string(),
        status: 200,
    })
}

fn init_tracing() {
    let tracer = opentelemetry_zipkin::new_pipeline()
        .with_service_name("rust-axum-service")
        .with_collector_endpoint("http://localhost:9411/api/v2/spans")
        .install_batch(opentelemetry_sdk::runtime::Tokio)
        .expect("Failed to initialize tracing pipeline");

    let otel_layer = tracing_opentelemetry::layer().with_tracer(tracer);

    tracing::subscriber::set_global_default(Registry::default().with(otel_layer))
        .expect("setting default subscriber failed");
}

Cargo.toml

[dependencies]
axum = "0.6"
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tracing = "0.1"
tracing-subscriber = "0.3"
tracing-opentelemetry = "0.28.0"
opentelemetry = { version = "0.27" }
opentelemetry-zipkin = {version = "0.27.0", features = ["reqwest-client"]}
opentelemetry_sdk = {version = "0.27.0", features = ["rt-tokio"]}
opentelemetry-http = "0.27.0"
reqwest = "0.12.9"

Stack Trace

thread 'main' panicked at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/blocking/shutdown.rs:51:21:
Cannot drop a runtime in a context where blocking is not allowed. This happens when a runtime is dropped from within an asynchronous context.
stack backtrace:
   0: rust_begin_unwind
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/std/src/panicking.rs:645:5
   1: core::panicking::panic_fmt
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/panicking.rs:72:14
   2: tokio::runtime::blocking::shutdown::Receiver::wait
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/blocking/shutdown.rs:51:21
   3: tokio::runtime::blocking::pool::BlockingPool::shutdown
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/blocking/pool.rs:263:12
   4: <tokio::runtime::blocking::pool::BlockingPool as core::ops::drop::Drop>::drop
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/blocking/pool.rs:284:9
   5: core::ptr::drop_in_place<tokio::runtime::blocking::pool::BlockingPool>
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ptr/mod.rs:498:1
   6: core::ptr::drop_in_place<tokio::runtime::runtime::Runtime>
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ptr/mod.rs:498:1
   7: reqwest::blocking::wait::enter
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/reqwest-0.12.9/src/blocking/wait.rs:76:21
   8: reqwest::blocking::wait::timeout
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/reqwest-0.12.9/src/blocking/wait.rs:13:5
   9: reqwest::blocking::client::ClientHandle::new
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/reqwest-0.12.9/src/blocking/client.rs:1208:15
  10: reqwest::blocking::client::ClientBuilder::build
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/reqwest-0.12.9/src/blocking/client.rs:106:9
  11: <opentelemetry_zipkin::exporter::ZipkinPipelineBuilder as core::default::Default>::default
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/opentelemetry-zipkin-0.27.0/src/exporter/mod.rs:61:17
  12: opentelemetry_zipkin::exporter::new_pipeline
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/opentelemetry-zipkin-0.27.0/src/exporter/mod.rs:42:5
  13: web_server::init_tracing
             at ./src/main.rs:47:18
  14: web_server::main::{{closure}}
             at ./src/main.rs:15:5
  15: tokio::runtime::park::CachedParkThread::block_on::{{closure}}
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/park.rs:281:63
  16: tokio::runtime::coop::with_budget
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/coop.rs:107:5
  17: tokio::runtime::coop::budget
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/coop.rs:73:5
  18: tokio::runtime::park::CachedParkThread::block_on
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/park.rs:281:31
  19: tokio::runtime::context::blocking::BlockingRegionGuard::block_on
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/context/blocking.rs:66:9
  20: tokio::runtime::scheduler::multi_thread::MultiThread::block_on::{{closure}}
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/multi_thread/mod.rs:87:13
  21: tokio::runtime::context::runtime::enter_runtime
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/context/runtime.rs:65:16
  22: tokio::runtime::scheduler::multi_thread::MultiThread::block_on
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/multi_thread/mod.rs:86:9
  23: tokio::runtime::runtime::Runtime::block_on_inner
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/runtime.rs:370:45
  24: tokio::runtime::runtime::Runtime::block_on
             at /Users/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/runtime.rs:342:13
  25: web_server::main
             at ./src/main.rs:24:5
  26: core::ops::function::FnOnce::call_once
             at /rustc/82e1608dfa6e0b5569232559e3d385fea5a93112/library/core/src/ops/function.rs:250:5

Judging from the stack trace, you are using reqwest's blocking API within an async context.

This did point me to the default-features = false setting in opentelemetry-zipkin which does resolve the issue.

Yeah, looks like reqwest-blocking-client is a default feature which overrides the (non-default) reqwest-client feature. (Probably they wish Cargo had exclusive features, but that still seems like an odd arrangement to me.)

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.