Repository: open-telemetry/opentelemetry-rust

Issue #1745: [Bug]: `opentelemetry_appender_tracing` does not work with blocking otlp exporter
Created: 2024-05-12T11:09:28Z
What happened?
The basic example for opentelemetry_appender_tracing is working fine for me.
The same example also works if I use an OTLP exporter with tonic and Tokio runtime within an async context.
However, if I modify the example for opentelemetry_appender_tracing to use an OTLP exporter with reqwest::blocking, the program enters into a deadlock.
This is the code I'm running:
use opentelemetry::KeyValue;
use opentelemetry_appender_tracing::layer;
use opentelemetry_sdk::{
    logs::{Config, LoggerProvider},
    Resource,
};
use tracing::error;
use tracing_subscriber::prelude::*;

fn main() {
    // This exporter is built with reqwest:blocking and will hang
    let otl_exporter = opentelemetry_otlp::new_exporter()
        .http()
        .build_log_exporter()
        .unwrap();
    let provider: LoggerProvider = LoggerProvider::builder()
        .with_config(
            Config::default().with_resource(Resource::new(vec![KeyValue::new(
                "service.name",
                "log-appender-tracing-example",
            )])),
        )
        .with_simple_exporter(otl_exporter)
        .build();
    let layer = layer::OpenTelemetryTracingBridge::new(&provider);
    tracing_subscriber::registry().with(layer).init();

    error!(name: "my-event-name", target: "my-system", event_id = 20, user_name = "otel", user_email = "otel@opentelemetry.io");
    drop(provider);
}
The opentelemetry-otlp crate is used with both reqwest blocking and tonic within an internal config crate:
opentelemetry-otlp = { version = "0.15.0", features = ["logs", "grpc-tonic", "http-proto", "reqwest-blocking-client", "serialize", "metrics", "trace"] }

API Version
I don't know
SDK Version
0.22.1
What Exporters are you seeing the problem on?
OTLP
Relevant log output
No response

Duplicate issue #2188: SimpleExporter is not useable with OTLP/gRPC 
Created: 2024-10-09T18:38:31Z
SimpleExporter is not useable with OTLP/gRPC (Tonic client used for gRPC)
Minimal repro:
use tracing::info;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::Registry;
use tracing_subscriber::util::SubscriberInitExt;
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
use opentelemetry_otlp::WithExportConfig;

fn main() {
    let logger_provider =  opentelemetry_otlp::new_pipeline()
    .logging()
    .with_exporter(
        opentelemetry_otlp::new_exporter()
            .tonic()
            .with_endpoint("http://localhost:4317"),
    )
    .install_simple().unwrap();

    // Create a new OpenTelemetryTracingBridge using the above LoggerProvider.
    let layer = OpenTelemetryTracingBridge::new(&logger_provider);
    tracing_subscriber::registry()
        .with(layer)
        .init();

    info!(name: "my-event", target: "my-target", "hello from {}. My price is {}", "apple", 1.99);

    let _ = logger_provider.shutdown();
}
Panics with
there is no reactor running, must be called from the context of a Tokio 1.x runtime
If making the main as tokio::main, then export hangs forever.
Need to modify exporters in such a way that they don't require async runtimes, and can do normal blocking calls (assuming there are APIs to do that).

Closing comment (2024-10-16T19:57:54Z): @cijothomas I see you mentioned that exporter hangs with tokio::main. Was it because of the infinite loop scenario similar to #1745

Yes exactly. Its deadlock caused by reentrancy in SimpleLogProcessor.