1use std::env::VarError;
2
3use opentelemetry_otlp::{
4 OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
5 OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, OTEL_EXPORTER_OTLP_PROTOCOL,
6 OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
7};
8
9const OTEL_SDK_DISABLED: &str = "OTEL_SDK_DISABLED";
10const OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL";
11const OTEL_EXPORTER_OTLP_METRICS_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL";
12const OTEL_EXPORTER_OTLP_LOGS_PROTOCOL: &str = "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL";
13const SPIN_DISABLE_LOG_TO_TRACING: &str = "SPIN_DISABLE_LOG_TO_TRACING";
14
15pub(crate) fn otel_tracing_enabled() -> bool {
23 any_vars_set(&[
24 OTEL_EXPORTER_OTLP_ENDPOINT,
25 OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
26 ]) && !otel_sdk_disabled()
27}
28
29pub(crate) fn otel_metrics_enabled() -> bool {
37 any_vars_set(&[
38 OTEL_EXPORTER_OTLP_ENDPOINT,
39 OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
40 ]) && !otel_sdk_disabled()
41}
42
43pub(crate) fn otel_logs_enabled() -> bool {
51 any_vars_set(&[
52 OTEL_EXPORTER_OTLP_ENDPOINT,
53 OTEL_EXPORTER_OTLP_LOGS_ENDPOINT,
54 ]) && !otel_sdk_disabled()
55}
56
57pub(crate) fn spin_disable_log_to_tracing() -> bool {
63 any_vars_set(&[SPIN_DISABLE_LOG_TO_TRACING])
64}
65
66fn any_vars_set(enabling_vars: &[&str]) -> bool {
67 enabling_vars
68 .iter()
69 .any(|key| std::env::var_os(key).is_some_and(|val| !val.is_empty()))
70}
71
72pub(crate) fn otel_sdk_disabled() -> bool {
76 std::env::var_os(OTEL_SDK_DISABLED).is_some_and(|val| !val.is_empty())
77}
78
79#[derive(Debug)]
81pub(crate) enum OtlpProtocol {
82 Grpc,
83 HttpProtobuf,
84 HttpJson,
85}
86
87impl OtlpProtocol {
88 pub(crate) fn traces_protocol_from_env() -> Self {
90 Self::protocol_from_env(
91 std::env::var(OTEL_EXPORTER_OTLP_TRACES_PROTOCOL),
92 std::env::var(OTEL_EXPORTER_OTLP_PROTOCOL),
93 )
94 }
95
96 pub(crate) fn metrics_protocol_from_env() -> Self {
98 Self::protocol_from_env(
99 std::env::var(OTEL_EXPORTER_OTLP_METRICS_PROTOCOL),
100 std::env::var(OTEL_EXPORTER_OTLP_PROTOCOL),
101 )
102 }
103
104 pub(crate) fn logs_protocol_from_env() -> Self {
106 Self::protocol_from_env(
107 std::env::var(OTEL_EXPORTER_OTLP_LOGS_PROTOCOL),
108 std::env::var(OTEL_EXPORTER_OTLP_PROTOCOL),
109 )
110 }
111
112 fn protocol_from_env(
113 specific_protocol: Result<String, VarError>,
114 general_protocol: Result<String, VarError>,
115 ) -> Self {
116 let protocol =
117 specific_protocol.unwrap_or(general_protocol.unwrap_or("http/protobuf".to_string()));
118
119 static WARN_ONCE: std::sync::Once = std::sync::Once::new();
120
121 match protocol.as_str() {
122 "grpc" => Self::Grpc,
123 "http/protobuf" => Self::HttpProtobuf,
124 "http/json" => Self::HttpJson,
125 s => {
126 WARN_ONCE.call_once(|| {
127 terminal::warn!(
128 "'{s}' is not a valid OTLP protocol, defaulting to http/protobuf"
129 );
130 });
131 Self::HttpProtobuf
132 }
133 }
134 }
135}