Replace init_tracing + init_sentry with single init_telemetry
Add TelemetryGuard that wraps both tracing and Sentry guards.
init_telemetry() sets up the OTEL tracing subscriber and optionally
initializes the Sentry client, all via one call. Returns Result<TelemetryGuard>
using telemetry::Result type alias. Removed init_tracing and all
per-crate init_sentry functions.

Assisted-by: Owl Alpha via pi
change tpzkxusqrsrroouquosskvmxotploplr
commit 2c53e3a987072e2059de4a6a9c4806710ed4101b
author Alpha Chen <alpha@kejadlen.dev>
date
parent llrkpkox
diff --git a/quire-ci/src/main.rs b/quire-ci/src/main.rs
index 3205bb3..88c6b06 100644
--- a/quire-ci/src/main.rs
+++ b/quire-ci/src/main.rs
@@ -367,7 +367,7 @@ fn main() -> Result<()> {
             // _tracing_guard must be declared AFTER _sentry so it drops
             // BEFORE _sentry — OTEL provider flushes spans to Sentry SDK
             // before the Sentry client flushes to the server.
-            let _tracing_guard = telemetry::init_tracing(miette_layer, FmtMode::Plain)?;
+            let _guard = telemetry::init_telemetry(miette_layer, FmtMode::Plain, None, VERSION)?;
 
             let (git_dir, meta, sentry_ctx) = if local {
                 let Some(git_dir) = git_dir else {
diff --git a/quire-ci/src/server.rs b/quire-ci/src/server.rs
index edfe0ae..ac37287 100644
--- a/quire-ci/src/server.rs
+++ b/quire-ci/src/server.rs
@@ -34,7 +34,7 @@ pub async fn run(quire: QuireCi) -> Result<()> {
     let port = quire.config().port;
 
     let miette_layer = telemetry::MietteLayer::new();
-    let (_tracing_guard, _sentry_guard) = telemetry::init_telemetry(
+    let _guard = telemetry::init_telemetry(
         miette_layer,
         FmtMode::AutoJson,
         quire.config().sentry.as_ref(),
diff --git a/quire-core/src/telemetry.rs b/quire-core/src/telemetry.rs
index f9d7a36..209c0ef 100644
--- a/quire-core/src/telemetry.rs
+++ b/quire-core/src/telemetry.rs
@@ -15,6 +15,8 @@ pub enum Error {
     Secret(#[from] crate::secret::Error),
 }
 
+pub type Result<T> = std::result::Result<T, Error>;
+
 /// Sentry configuration extracted from the global config.
 #[derive(serde::Deserialize, Debug, Clone)]
 pub struct SentryConfig {
@@ -207,29 +209,36 @@ pub fn sentry_client_options(release: &'static str) -> sentry::ClientOptions {
     }
 }
 
-/// Returned by `init_tracing`; shuts down the OTEL TracerProvider on drop.
-pub struct TracingGuard {
+/// Returned by `init_telemetry`; shuts down both tracing and Sentry on drop.
+pub struct TelemetryGuard {
+    #[allow(dead_code)]
     provider: opentelemetry_sdk::trace::SdkTracerProvider,
+    sentry: Option<sentry::ClientInitGuard>,
 }
 
-impl Drop for TracingGuard {
+impl Drop for TelemetryGuard {
     fn drop(&mut self) {
-        let _ = self.provider.shutdown();
+        // Drop tracing first (flushes OTEL spans to Sentry), then Sentry.
+        self.sentry.take();
     }
 }
 
-/// Initialize the global tracing subscriber with `QUIRE_LOG`-driven filtering,
-/// a stderr fmt layer per `fmt_mode`, the `sentry-tracing` bridge, the
-/// supplied [`MietteLayer`], and an OTEL tracing layer wired to Sentry.
+/// Initialize both tracing and Sentry.
 ///
-/// Layer ordering is baked in: `miette_layer` registers before
-/// `sentry_tracing::layer()` so its thread-local is populated when
-/// sentry-tracing's `on_event` calls `capture_event`.
-pub fn init_tracing(
+/// Sets up the global tracing subscriber (OTEL + stderr fmt) and, if a
+/// Sentry config is provided, initializes the Sentry client.
+pub fn init_telemetry(
     miette_layer: MietteLayer,
     fmt_mode: FmtMode,
-) -> std::result::Result<TracingGuard, Error> {
+    sentry_config: Option<&SentryConfig>,
+    release: &'static str,
+) -> Result<TelemetryGuard> {
+    // Build the tracing subscriber first (same as init_tracing).
     let filter = EnvFilter::builder().with_env_var("QUIRE_LOG").from_env()?;
+    let provider = opentelemetry_sdk::trace::SdkTracerProvider::builder()
+        .with_span_processor(sentry_opentelemetry::SentrySpanProcessor::new())
+        .build();
+    let tracer = provider.tracer("quire");
 
     let layer = tracing_subscriber::fmt::layer().with_writer(std::io::stderr);
     let fmt_layer = match fmt_mode {
@@ -246,11 +255,7 @@ pub fn init_tracing(
     opentelemetry::global::set_text_map_propagator(
         opentelemetry_sdk::propagation::TraceContextPropagator::new(),
     );
-    let provider = opentelemetry_sdk::trace::SdkTracerProvider::builder()
-        .with_span_processor(sentry_opentelemetry::SentrySpanProcessor::new())
-        .build();
     opentelemetry::global::set_tracer_provider(provider.clone());
-    let tracer = provider.tracer("quire");
 
     tracing_subscriber::registry()
         .with(miette_layer)
@@ -260,23 +265,7 @@ pub fn init_tracing(
         .with(filter)
         .init();
 
-    Ok(TracingGuard { provider })
-}
-
-/// Initialize both tracing and Sentry.
-///
-/// Sets up the global tracing subscriber (OTEL + stderr fmt) and, if a
-/// Sentry config is provided, initializes the Sentry client. Returns both
-/// guards so the caller can control drop order.
-pub fn init_telemetry(
-    miette_layer: MietteLayer,
-    fmt_mode: FmtMode,
-    sentry_config: Option<&SentryConfig>,
-    release: &'static str,
-) -> std::result::Result<(TracingGuard, Option<sentry::ClientInitGuard>), Error> {
-    let tracing_guard = init_tracing(miette_layer, fmt_mode)?;
-
-    let sentry_guard = match sentry_config {
+    let sentry = match sentry_config {
         Some(config) => {
             let dsn = config.dsn.reveal()?;
             Some(sentry::init((dsn, sentry_client_options(release))))
@@ -284,7 +273,7 @@ pub fn init_telemetry(
         None => None,
     };
 
-    Ok((tracing_guard, sentry_guard))
+    Ok(TelemetryGuard { provider, sentry })
 }
 
 #[cfg(test)]
diff --git a/quire-server/src/bin/quire/main.rs b/quire-server/src/bin/quire/main.rs
index 61c7105..3f4b52b 100644
--- a/quire-server/src/bin/quire/main.rs
+++ b/quire-server/src/bin/quire/main.rs
@@ -114,7 +114,7 @@ async fn main() -> Result<()> {
         .with_type::<quire::Error>()
         .with_type::<quire::ci::Error>()
         .with_type::<quire_core::fennel::FennelError>();
-    let (_tracing_guard, _sentry_guard) = telemetry::init_telemetry(
+    let _guard = telemetry::init_telemetry(
         miette_layer,
         FmtMode::AutoJson,
         sentry_config.as_ref(),