From cce5b66dba401ce6bef3c624f5ff17343a8cb849 Mon Sep 17 00:00:00 2001 From: Liona Can Date: Thu, 13 Aug 2026 05:44:40 -0400 Subject: [PATCH] fix(observability): shut down tracer provider --- src/bin/dolos/common.rs | 19 +++++++++++++++++++ src/bin/dolos/main.rs | 7 +++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/bin/dolos/common.rs b/src/bin/dolos/common.rs index 8e74c9bf4..9cf5b83c3 100644 --- a/src/bin/dolos/common.rs +++ b/src/bin/dolos/common.rs @@ -7,7 +7,9 @@ use dolos_snapshot::registry::Auth; use miette::{Context as _, IntoDiagnostic}; use opentelemetry::trace::TracerProvider as _; use opentelemetry_otlp::WithExportConfig as _; +use opentelemetry_sdk::trace::SdkTracerProvider; use std::sync::Arc; +use std::sync::OnceLock; use std::{fs, path::PathBuf, time::Duration}; use tokio_util::sync::CancellationToken; use tracing::{debug, info}; @@ -20,6 +22,8 @@ use dolos::storage; pub type Stores = storage::Stores; +static TRACER_PROVIDER: OnceLock = OnceLock::new(); + /// Ensure the storage root directory exists. pub fn ensure_storage_path(config: &RootConfig) -> Result { storage::ensure_storage_path(config) @@ -285,6 +289,7 @@ pub fn setup_tracing(config: &LoggingConfig, telemetry: &TelemetryConfig) -> mie .build(); opentelemetry::global::set_tracer_provider(tracer.clone()); + let _ = TRACER_PROVIDER.set(tracer.clone()); let layer = tracing_opentelemetry::layer().with_tracer(tracer.tracer("dolos")); Some(layer) @@ -319,6 +324,20 @@ pub fn setup_tracing(config: &LoggingConfig, telemetry: &TelemetryConfig) -> mie Ok(()) } +/// Flush and stop the batch span exporter before the process exits. +/// +/// The global provider owns a clone, so merely dropping the local provider from +/// `setup_tracing` does not stop its worker or export its final batch. Keeping a +/// handle here lets the CLI perform an explicit shutdown after every command, +/// including commands that do not run the long-lived daemon pipeline. +pub fn shutdown_tracing() { + if let Some(provider) = TRACER_PROVIDER.get() { + if let Err(error) = provider.shutdown() { + eprintln!("failed to shut down OpenTelemetry tracer provider: {error}"); + } + } +} + pub fn open_genesis_files(config: &GenesisConfig) -> miette::Result { Genesis::from_file_paths( &config.byron_path, diff --git a/src/bin/dolos/main.rs b/src/bin/dolos/main.rs index a10aeb429..3625269aa 100644 --- a/src/bin/dolos/main.rs +++ b/src/bin/dolos/main.rs @@ -92,7 +92,7 @@ fn main() -> Result<()> { let feedback = crate::feedback::Feedback::default(); - match (config, args.command) { + let result = match (config, args.command) { (Ok(config), Command::Daemon(args)) => daemon::run(config, &args), (Ok(config), Command::Sync(args)) => sync::run(&config, &args), (Ok(config), Command::Serve(args)) => serve::run(config, &args), @@ -119,5 +119,8 @@ fn main() -> Result<()> { (Ok(config), Command::Minikupo(x)) => minikupo::run(&config, &x), (Err(x), _) => Err(x), - } + }; + + crate::common::shutdown_tracing(); + result }