scuffle_bootstrap_telemetry/
opentelemetry.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
pub use ::opentelemetry::*;

/// OpenTelemetry error.
///
/// This enum represents all possible errors that can occur when working with OpenTelemetry.
#[derive(Debug, thiserror::Error)]
pub enum OpenTelemetryError {
    #[cfg(feature = "opentelemetry-metrics")]
    #[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry-metrics")))]
    #[error("metrics: {0}")]
    Metrics(#[from] opentelemetry_sdk::metrics::MetricError),
    #[cfg(feature = "opentelemetry-traces")]
    #[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry-traces")))]
    #[error("traces: {0}")]
    Traces(#[from] opentelemetry::trace::TraceError),
    #[cfg(feature = "opentelemetry-logs")]
    #[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry-logs")))]
    #[error("logs: {0}")]
    Logs(#[from] opentelemetry_sdk::logs::LogError),
}

/// OpenTelemetry configuration.
///
/// This struct contains different OpenTelemetry providers for metrics, traces, and logs.
/// If set, these providers will be used to collect and export telemetry data.
#[derive(Debug, Default, Clone)]
pub struct OpenTelemetry {
    #[cfg(feature = "opentelemetry-metrics")]
    #[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry-metrics")))]
    metrics: Option<opentelemetry_sdk::metrics::SdkMeterProvider>,
    #[cfg(feature = "opentelemetry-traces")]
    #[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry-traces")))]
    traces: Option<opentelemetry_sdk::trace::TracerProvider>,
    #[cfg(feature = "opentelemetry-logs")]
    #[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry-logs")))]
    logs: Option<opentelemetry_sdk::logs::LoggerProvider>,
}

impl OpenTelemetry {
    /// Creates a new empty OpenTelemetry configuration.
    pub fn new() -> Self {
        Self::default()
    }

    /// Checks if any of the providers are enabled.
    pub fn is_enabled(&self) -> bool {
        #[cfg_attr(
            not(any(
                feature = "opentelemetry-metrics",
                feature = "opentelemetry-traces",
                feature = "opentelemetry-logs"
            )),
            allow(unused_mut)
        )]
        let mut enabled = false;
        #[cfg(feature = "opentelemetry-metrics")]
        {
            enabled |= self.metrics.is_some();
        }
        #[cfg(feature = "opentelemetry-traces")]
        {
            enabled |= self.traces.is_some();
        }
        #[cfg(feature = "opentelemetry-logs")]
        {
            enabled |= self.logs.is_some();
        }
        enabled
    }

    /// Sets the metrics provider.
    #[cfg(feature = "opentelemetry-metrics")]
    #[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry-metrics")))]
    pub fn with_metrics(self, metrics: impl Into<Option<opentelemetry_sdk::metrics::SdkMeterProvider>>) -> Self {
        Self {
            metrics: metrics.into(),
            #[cfg(feature = "opentelemetry-traces")]
            traces: self.traces,
            #[cfg(feature = "opentelemetry-logs")]
            logs: self.logs,
        }
    }

    /// Sets the traces provider.
    #[cfg(feature = "opentelemetry-traces")]
    #[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry-traces")))]
    pub fn with_traces(self, traces: impl Into<Option<opentelemetry_sdk::trace::TracerProvider>>) -> Self {
        Self {
            traces: traces.into(),
            #[cfg(feature = "opentelemetry-metrics")]
            metrics: self.metrics,
            #[cfg(feature = "opentelemetry-logs")]
            logs: self.logs,
        }
    }

    /// Sets the logs provider.
    #[cfg(feature = "opentelemetry-logs")]
    #[cfg_attr(docsrs, doc(cfg(feature = "opentelemetry-logs")))]
    pub fn with_logs(self, logs: impl Into<Option<opentelemetry_sdk::logs::LoggerProvider>>) -> Self {
        Self {
            logs: logs.into(),
            #[cfg(feature = "opentelemetry-traces")]
            traces: self.traces,
            #[cfg(feature = "opentelemetry-metrics")]
            metrics: self.metrics,
        }
    }

    /// Flushes all metrics, traces, and logs.
    ///
    /// <div class="warning">Warning: This blocks the current thread.</div>
    pub fn flush(&self) -> Result<(), OpenTelemetryError> {
        #[cfg(feature = "opentelemetry-metrics")]
        if let Some(metrics) = &self.metrics {
            metrics.force_flush()?;
        }

        #[cfg(feature = "opentelemetry-traces")]
        if let Some(traces) = &self.traces {
            for r in traces.force_flush() {
                r?;
            }
        }

        #[cfg(feature = "opentelemetry-logs")]
        if let Some(logs) = &self.logs {
            for r in logs.force_flush() {
                r?;
            }
        }

        Ok(())
    }

    /// Shuts down all metrics, traces, and logs.
    pub fn shutdown(&self) -> Result<(), OpenTelemetryError> {
        #[cfg(feature = "opentelemetry-metrics")]
        if let Some(metrics) = &self.metrics {
            metrics.shutdown()?;
        }

        #[cfg(feature = "opentelemetry-traces")]
        if let Some(traces) = &self.traces {
            traces.shutdown()?;
        }

        #[cfg(feature = "opentelemetry-logs")]
        if let Some(logs) = &self.logs {
            logs.shutdown()?;
        }

        Ok(())
    }
}