Skip to content

Commit 00ed1c4

Browse files
feat: add support for OTEL_SDK_DISABLED environment variable
Signed-off-by: Saurav Sharma <appdroiddeveloper@gmail.com>
1 parent 42139cb commit 00ed1c4

File tree

4 files changed

+64
-12
lines changed

4 files changed

+64
-12
lines changed

opentelemetry-sdk/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
- *Fix* SpanProcessor::on_start is no longer called on non recording spans
77
- **Fix**: Restore true parallel exports in the async-native `BatchSpanProcessor` by honoring `OTEL_BSP_MAX_CONCURRENT_EXPORTS` ([#2959](https://github.com/open-telemetry/opentelemetry-rust/pull/3028)). A regression in [#2685](https://github.com/open-telemetry/opentelemetry-rust/pull/2685) inadvertently awaited the `export()` future directly in `opentelemetry-sdk/src/trace/span_processor_with_async_runtime.rs` instead of spawning it on the runtime, forcing all exports to run sequentially.
88
- **Feature**: Added `Clone` implementation to `SdkLogger` for API consistency with `SdkTracer` ([#3058](https://github.com/open-telemetry/opentelemetry-rust/issues/3058)).
9+
- **Feature**: Add support for `OTEL_SDK_DISABLED` environment variable
10+
911

1012
## 0.30.0
1113

opentelemetry-sdk/src/logs/logger_provider.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,33 @@ use std::{
1212
},
1313
};
1414

15-
// a no nop logger provider used as placeholder when the provider is shutdown
15+
// a no op logger provider used as placeholder when the provider is shutdown
1616
// TODO - replace it with LazyLock once it is stable
17-
static NOOP_LOGGER_PROVIDER: OnceLock<SdkLoggerProvider> = OnceLock::new();
17+
static SHUTDOWN_LOGGER_PROVIDER: OnceLock<SdkLoggerProvider> = OnceLock::new();
1818

1919
#[inline]
20-
fn noop_logger_provider() -> &'static SdkLoggerProvider {
21-
NOOP_LOGGER_PROVIDER.get_or_init(|| SdkLoggerProvider {
20+
fn shutdown_logger_provider() -> &'static SdkLoggerProvider {
21+
SHUTDOWN_LOGGER_PROVIDER.get_or_init(|| SdkLoggerProvider {
2222
inner: Arc::new(LoggerProviderInner {
2323
processors: Vec::new(),
2424
is_shutdown: AtomicBool::new(true),
2525
}),
2626
})
2727
}
28+
// a no op logger provider used as placeholder when sdk is disabled with
29+
// help of environment variable `OTEL_SDK_DISABLED`
30+
// TODO - replace it with LazyLock once it is stable
31+
static DISABLED_LOGGER_PROVIDER: OnceLock<SdkLoggerProvider> = OnceLock::new();
32+
33+
#[inline]
34+
fn disabled_logger_provider() -> &'static SdkLoggerProvider {
35+
DISABLED_LOGGER_PROVIDER.get_or_init(|| SdkLoggerProvider {
36+
inner: Arc::new(LoggerProviderInner {
37+
processors: Vec::new(),
38+
is_shutdown: AtomicBool::new(false),
39+
}),
40+
})
41+
}
2842

2943
#[derive(Debug, Clone)]
3044
/// Handles the creation and coordination of [`Logger`]s.
@@ -53,13 +67,21 @@ impl opentelemetry::logs::LoggerProvider for SdkLoggerProvider {
5367
}
5468

5569
fn logger_with_scope(&self, scope: InstrumentationScope) -> Self::Logger {
56-
// If the provider is shutdown, new logger will refer a no-op logger provider.
70+
// If the provider is shutdown, new logger will refer a shutdown no-op logger provider.
5771
if self.inner.is_shutdown.load(Ordering::Relaxed) {
5872
otel_debug!(
5973
name: "LoggerProvider.NoOpLoggerReturned",
6074
logger_name = scope.name(),
6175
);
62-
return SdkLogger::new(scope, noop_logger_provider().clone());
76+
return SdkLogger::new(scope, shutdown_logger_provider().clone());
77+
}
78+
// If the provider is disabled, new logger will refer a dosabled no-op logger provider.
79+
if std::env::var("OTEL_SDK_DISABLED").is_ok_and(|var| var.to_lowercase() == "true") {
80+
otel_debug!(
81+
name: "LoggerProvider.NoOpLoggerReturned",
82+
logger_name = scope.name(),
83+
);
84+
return SdkLogger::new(scope, disabled_logger_provider().clone());
6385
}
6486
if scope.name().is_empty() {
6587
otel_info!(name: "LoggerNameEmpty", message = "Logger name is empty; consider providing a meaningful name. Logger will function normally and the provided name will be used as-is.");

opentelemetry-sdk/src/metrics/meter_provider.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,9 @@ impl MeterProvider for SdkMeterProvider {
189189
}
190190

191191
fn meter_with_scope(&self, scope: InstrumentationScope) -> Meter {
192-
if self.inner.shutdown_invoked.load(Ordering::Relaxed) {
192+
if self.inner.shutdown_invoked.load(Ordering::Relaxed)
193+
|| std::env::var("OTEL_SDK_DISABLED").is_ok_and(|var| var.to_lowercase() == "true")
194+
{
193195
otel_debug!(
194196
name: "MeterProvider.NoOpMeterReturned",
195197
meter_name = scope.name(),

opentelemetry-sdk/src/trace/provider.rs

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ use std::time::Duration;
7979

8080
static PROVIDER_RESOURCE: OnceLock<Resource> = OnceLock::new();
8181

82-
// a no nop tracer provider used as placeholder when the provider is shutdown
82+
// a no op tracer provider used as placeholder when the provider is shutdown
8383
// TODO Replace with LazyLock once it is stable
84-
static NOOP_TRACER_PROVIDER: OnceLock<SdkTracerProvider> = OnceLock::new();
84+
static SHUTDOWN_TRACER_PROVIDER: OnceLock<SdkTracerProvider> = OnceLock::new();
8585
#[inline]
86-
fn noop_tracer_provider() -> &'static SdkTracerProvider {
87-
NOOP_TRACER_PROVIDER.get_or_init(|| {
86+
fn shutdown_tracer_provider() -> &'static SdkTracerProvider {
87+
SHUTDOWN_TRACER_PROVIDER.get_or_init(|| {
8888
SdkTracerProvider {
8989
inner: Arc::new(TracerProviderInner {
9090
processors: Vec::new(),
@@ -101,6 +101,29 @@ fn noop_tracer_provider() -> &'static SdkTracerProvider {
101101
})
102102
}
103103

104+
// a no op tracer provider used as placeholder when sdk is disabled with
105+
// help of environment variable `OTEL_SDK_DISABLED`
106+
// TODO Replace with LazyLock once it is stable
107+
static DISABLED_TRACER_PROVIDER: OnceLock<SdkTracerProvider> = OnceLock::new();
108+
#[inline]
109+
fn disabled_tracer_provider() -> &'static SdkTracerProvider {
110+
DISABLED_TRACER_PROVIDER.get_or_init(|| {
111+
SdkTracerProvider {
112+
inner: Arc::new(TracerProviderInner {
113+
processors: Vec::new(),
114+
config: Config {
115+
// cannot use default here as the default resource is not empty
116+
sampler: Box::new(Sampler::ParentBased(Box::new(Sampler::AlwaysOn))),
117+
id_generator: Box::<RandomIdGenerator>::default(),
118+
span_limits: SpanLimits::default(),
119+
resource: Cow::Owned(Resource::empty()),
120+
},
121+
is_shutdown: AtomicBool::new(false),
122+
}),
123+
}
124+
})
125+
}
126+
104127
/// TracerProvider inner type
105128
#[derive(Debug)]
106129
pub(crate) struct TracerProviderInner {
@@ -286,7 +309,10 @@ impl opentelemetry::trace::TracerProvider for SdkTracerProvider {
286309

287310
fn tracer_with_scope(&self, scope: InstrumentationScope) -> Self::Tracer {
288311
if self.inner.is_shutdown.load(Ordering::Relaxed) {
289-
return SdkTracer::new(scope, noop_tracer_provider().clone());
312+
return SdkTracer::new(scope, shutdown_tracer_provider().clone());
313+
}
314+
if std::env::var("OTEL_SDK_DISABLED").is_ok_and(|var| var.to_lowercase() == "true") {
315+
return SdkTracer::new(scope, disabled_tracer_provider().clone());
290316
}
291317
if scope.name().is_empty() {
292318
otel_info!(name: "TracerNameEmpty", message = "Tracer name is empty; consider providing a meaningful name. Tracer will function normally and the provided name will be used as-is.");

0 commit comments

Comments
 (0)