use anyhow::Context; use opentelemetry::trace::TracerProvider; use opentelemetry_otlp::{SpanExporter, WithExportConfig}; use opentelemetry_sdk::trace as sdktrace; use tracing_opentelemetry::layer; use tracing_subscriber::prelude::*; pub struct OtelGuard { provider: sdktrace::SdkTracerProvider, } impl OtelGuard { pub async fn shutdown(self) { if let Err(e) = self.provider.shutdown() { tracing::warn!(error = %e, "OTLP shutdown error"); } } } pub fn init_otel(endpoint: &str, service_name: &str) -> anyhow::Result { let exporter = SpanExporter::builder() .with_http() .with_endpoint(endpoint) .build() .context("build OTLP exporter")?; let tracer_provider = sdktrace::SdkTracerProvider::builder() .with_batch_exporter(exporter) .build(); let tracer = tracer_provider.tracer(service_name.to_string()); let otel_layer = layer().with_tracer(tracer); tracing_subscriber::registry() .with(otel_layer) .try_init() .context("install OTLP tracing subscriber")?; Ok(OtelGuard { provider: tracer_provider, }) }