init_tracing_opentelemetry/otlp/
mod.rs1#[cfg(feature = "metrics")]
2pub mod metrics;
3pub mod traces;
4
5#[cfg(feature = "metrics")]
6use opentelemetry::metrics::MeterProvider;
7#[cfg(feature = "metrics")]
8use opentelemetry_sdk::metrics::SdkMeterProvider;
9
10use opentelemetry::trace::TracerProvider;
11use opentelemetry_sdk::trace::SdkTracerProvider;
12
13#[must_use = "Recommend holding with 'let _guard = ' pattern to ensure final traces/metrics are sent to the server"]
14pub struct OtelGuard {
17 #[cfg(feature = "metrics")]
18 pub(crate) meter_provider: SdkMeterProvider,
19 pub(crate) tracer_provider: SdkTracerProvider,
20}
21
22impl OtelGuard {
23 #[must_use]
24 pub fn tracer_provider(&self) -> &impl TracerProvider {
25 &self.tracer_provider
26 }
27
28 #[cfg(feature = "metrics")]
29 #[must_use]
30 pub fn meter_provider(&self) -> &impl MeterProvider {
31 &self.meter_provider
32 }
33}
34
35impl Drop for OtelGuard {
36 #[allow(unused_must_use)]
37 fn drop(&mut self) {
38 let _ = self.tracer_provider.force_flush();
39 let _ = self.tracer_provider.shutdown();
40 #[cfg(feature = "metrics")]
41 {
42 let _ = self.meter_provider.force_flush();
43 let _ = self.meter_provider.shutdown();
44 }
45 }
46}
47
48#[allow(unused_mut)]
49pub(crate) fn infer_protocol(
50 maybe_protocol: Option<&str>,
51 maybe_endpoint: Option<&str>,
52) -> Option<String> {
53 let mut maybe_protocol = match (maybe_protocol, maybe_endpoint) {
54 (Some(protocol), _) => Some(protocol.to_string()),
55 (None, Some(endpoint)) => {
56 if endpoint.contains(":4317") {
57 Some("grpc".to_string())
58 } else {
59 Some("http/protobuf".to_string())
60 }
61 }
62 _ => None,
63 };
64 #[cfg(feature = "tls")]
65 if maybe_protocol.as_deref() == Some("grpc")
66 && maybe_endpoint.is_some_and(|e| e.starts_with("https"))
67 {
68 maybe_protocol = Some("grpc/tls".to_string());
69 }
70
71 maybe_protocol
72}
73
74#[cfg(test)]
75mod tests {
76 use assert2::assert;
77 use rstest::rstest;
78
79 use super::*;
80
81 #[rstest]
82 #[case(None, None, None)] #[case(Some("http/protobuf"), None, Some("http/protobuf"))] #[case(Some("grpc"), None, Some("grpc"))] #[case(None, Some("http://localhost:4317"), Some("grpc"))] #[cfg_attr(
87 feature = "tls",
88 case(None, Some("https://localhost:4317"), Some("grpc/tls"))
89 )]
90 #[cfg_attr(
91 feature = "tls",
92 case(Some("grpc/tls"), Some("https://localhost:4317"), Some("grpc/tls"))
93 )]
94 #[case(
95 Some("http/protobuf"),
96 Some("http://localhost:4318/v1/traces"), Some("http/protobuf"),
98 )]
99 #[case(
100 Some("http/protobuf"),
101 Some("https://examples.com:4318/v1/traces"),
102 Some("http/protobuf")
103 )]
104 #[case(
105 Some("http/protobuf"),
106 Some("https://examples.com:4317"),
107 Some("http/protobuf")
108 )]
109 fn test_infer_protocol(
110 #[case] traces_protocol: Option<&str>,
111 #[case] traces_endpoint: Option<&str>,
112 #[case] expected_protocol: Option<&str>,
113 ) {
114 assert!(infer_protocol(traces_protocol, traces_endpoint).as_deref() == expected_protocol);
115 }
116}