1use anyhow::Result;
2use opentelemetry_sdk::{
3 logs::SdkLoggerProvider, metrics::SdkMeterProvider, trace::SdkTracerProvider,
4};
5use tracing::warn;
6
7#[derive(Debug)]
18pub struct OtelGuard {
19 tracer_provider: Option<SdkTracerProvider>,
20 meter_provider: Option<SdkMeterProvider>,
21 logger_provider: Option<SdkLoggerProvider>,
22}
23
24impl OtelGuard {
25 pub fn new(
27 tracer_provider: Option<SdkTracerProvider>,
28 meter_provider: Option<SdkMeterProvider>,
29 logger_provider: Option<SdkLoggerProvider>,
30 ) -> Self {
31 Self {
32 tracer_provider,
33 meter_provider,
34 logger_provider,
35 }
36 }
37
38 pub fn with_tracer_provider(mut self, tracer_provider: SdkTracerProvider) -> Self {
40 self.tracer_provider = Some(tracer_provider);
41 self
42 }
43
44 pub fn with_meter_provider(mut self, meter_provider: SdkMeterProvider) -> Self {
46 self.meter_provider = Some(meter_provider);
47 self
48 }
49
50 pub fn with_logger_provider(mut self, logger_provider: SdkLoggerProvider) -> Self {
52 self.logger_provider = Some(logger_provider);
53 self
54 }
55
56 pub fn shutdown(mut self) -> Result<()> {
60 let mut errors = Vec::new();
61 if let Some(tracer_provider) = self.tracer_provider.take()
62 && let Err(err) = tracer_provider.shutdown()
63 {
64 errors.push(err);
65 }
66
67 if let Some(meter_provider) = self.meter_provider.take()
68 && let Err(err) = meter_provider.shutdown()
69 {
70 errors.push(err);
71 }
72
73 if let Some(logger_provider) = self.logger_provider.take()
74 && let Err(err) = logger_provider.shutdown()
75 {
76 errors.push(err);
77 }
78
79 match errors.is_empty() {
80 true => Ok(()),
81 false => Err(anyhow::anyhow!(
82 "Failed to shutdown some providers: {errors:?}"
83 )),
84 }
85 }
86}
87
88impl Drop for OtelGuard {
90 fn drop(&mut self) {
91 if let Some(tracer_provider) = self.tracer_provider.take()
92 && let Err(err) = tracer_provider.shutdown()
93 {
94 warn!("Failed to shutdown tracer provider: {err:?}");
95 }
96 if let Some(meter_provider) = self.meter_provider.take()
97 && let Err(err) = meter_provider.shutdown()
98 {
99 warn!("Failed to shutdown meter provider: {err:?}");
100 }
101 if let Some(logger_provider) = self.logger_provider.take()
102 && let Err(err) = logger_provider.shutdown()
103 {
104 warn!("Failed to shutdown logger provider: {err:?}");
105 }
106 }
107}