Skip to content

Commit 84646f2

Browse files
authored
feat(stackable-telemetry): Add support for env_var per configured subscriber (#801)
* feat(stackable-telemetry): add support for env_var per configured subscriber * chore(stackable-telemetry): update changelog * fix(stackable-telemetry): doc tests * fix(stackable-telemetry): remove unused code
1 parent 9ff61fa commit 84646f2

File tree

2 files changed

+71
-38
lines changed

2 files changed

+71
-38
lines changed

crates/stackable-telemetry/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Changed
8+
9+
- Add support for setting the environment variable for each configured tracing subscriber ([#801]).
10+
11+
[#801]: https://github.com/stackabletech/operator-rs/pull/801
12+
713
## [0.1.0] - 2024-05-08
814

915
### Changed

crates/stackable-telemetry/src/tracing.rs

+65-38
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use opentelemetry_sdk::{
1717
use opentelemetry_semantic_conventions::resource;
1818
use snafu::{ResultExt as _, Snafu};
1919
use tracing::{level_filters::LevelFilter, subscriber::SetGlobalDefaultError};
20-
use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Layer, Registry};
20+
use tracing_subscriber::{filter::Directive, layer::SubscriberExt, EnvFilter, Layer, Registry};
2121

2222
type Result<T, E = Error> = std::result::Result<T, E>;
2323

@@ -48,9 +48,9 @@ pub enum Error {
4848
/// async fn main() -> Result<(), Error> {
4949
/// let _tracing_guard = Tracing::builder()
5050
/// .service_name("test")
51-
/// .with_console_output(LevelFilter::INFO)
52-
/// .with_otlp_log_exporter(LevelFilter::DEBUG)
53-
/// .with_otlp_trace_exporter(LevelFilter::TRACE)
51+
/// .with_console_output("TEST_CONSOLE", LevelFilter::INFO)
52+
/// .with_otlp_log_exporter("TEST_OTLP_LOG", LevelFilter::DEBUG)
53+
/// .with_otlp_trace_exporter("TEST_OTLP_TRACE", LevelFilter::TRACE)
5454
/// .build()
5555
/// .init()?;
5656
///
@@ -138,20 +138,22 @@ impl Tracing {
138138
let mut layers: Vec<Box<dyn Layer<Registry> + Sync + Send>> = Vec::new();
139139

140140
if self.console_log_config.enabled {
141-
let env_filter_layer = EnvFilter::builder()
142-
.with_default_directive(self.console_log_config.level_filter.into()) // TODO (@NickLarsenNZ): support Directives
143-
.from_env_lossy();
141+
let env_filter_layer = env_filter_builder(
142+
self.console_log_config.env_var,
143+
self.console_log_config.default_level_filter,
144+
);
144145
let console_output_layer =
145146
tracing_subscriber::fmt::layer().with_filter(env_filter_layer);
146147
layers.push(console_output_layer.boxed());
147148
}
148149

149150
if self.otlp_log_config.enabled {
150-
let env_filter_layer = EnvFilter::builder()
151-
.with_default_directive(self.otlp_log_config.level_filter.into()) // TODO (@NickLarsenNZ): support Directives
152-
.from_env_lossy()
153-
// TODO (@NickLarsenNZ): Remove this directive once https://github.com/open-telemetry/opentelemetry-rust/issues/761 is resolved
154-
.add_directive("h2=off".parse().expect("invalid directive"));
151+
let env_filter_layer = env_filter_builder(
152+
self.otlp_log_config.env_var,
153+
self.otlp_log_config.default_level_filter,
154+
)
155+
// TODO (@NickLarsenNZ): Remove this directive once https://github.com/open-telemetry/opentelemetry-rust/issues/761 is resolved
156+
.add_directive("h2=off".parse().expect("invalid directive"));
155157

156158
let log_exporter = opentelemetry_otlp::new_exporter().tonic();
157159
let otel_log =
@@ -173,11 +175,12 @@ impl Tracing {
173175
}
174176

175177
if self.otlp_trace_config.enabled {
176-
let env_filter_layer = EnvFilter::builder()
177-
.with_default_directive(self.otlp_trace_config.level_filter.into()) // TODO (@NickLarsenNZ): support Directives
178-
.from_env_lossy()
179-
// TODO (@NickLarsenNZ): Remove this directive once https://github.com/open-telemetry/opentelemetry-rust/issues/761 is resolved
180-
.add_directive("h2=off".parse().expect("invalid directive"));
178+
let env_filter_layer = env_filter_builder(
179+
self.otlp_trace_config.env_var,
180+
self.otlp_trace_config.default_level_filter,
181+
)
182+
// TODO (@NickLarsenNZ): Remove this directive once https://github.com/open-telemetry/opentelemetry-rust/issues/761 is resolved
183+
.add_directive("h2=off".parse().expect("invalid directive"));
181184

182185
let trace_exporter = opentelemetry_otlp::new_exporter().tonic();
183186
let otel_tracer = opentelemetry_otlp::new_pipeline()
@@ -186,7 +189,7 @@ impl Tracing {
186189
.with_trace_config(
187190
trace::config()
188191
.with_sampler(Sampler::AlwaysOn) // TODO (@NickLarsenNZ): Make this configurable. See also Sampler::ParentBased
189-
.with_id_generator(RandomIdGenerator::default()) // TODO (@NickLarsenNZ): Is there a more appropriate ID generator?
192+
.with_id_generator(RandomIdGenerator::default())
190193
.with_resource(Resource::new(vec![KeyValue::new(
191194
resource::SERVICE_NAME,
192195
self.service_name,
@@ -308,14 +311,16 @@ pub struct TracingBuilder<S: BuilderState> {
308311
#[derive(Clone, Debug, PartialEq)]
309312
struct SubscriberConfig {
310313
enabled: bool,
311-
level_filter: LevelFilter,
314+
env_var: &'static str,
315+
default_level_filter: LevelFilter,
312316
}
313317

314318
impl Default for SubscriberConfig {
315319
fn default() -> Self {
316320
Self {
317321
enabled: false,
318-
level_filter: LevelFilter::OFF,
322+
env_var: EnvFilter::DEFAULT_ENV,
323+
default_level_filter: LevelFilter::OFF,
319324
}
320325
}
321326
}
@@ -333,58 +338,68 @@ impl TracingBuilder<builder_state::PreServiceName> {
333338
}
334339

335340
impl TracingBuilder<builder_state::Config> {
336-
/// Enable the console output tracing subscriber, and filter the log level.
341+
/// Enable the console output tracing subscriber and set the default
342+
/// [`LevelFilter`] which is overridable through the given environment
343+
/// variable.
337344
pub fn with_console_output(
338345
self,
339-
level_filter: LevelFilter,
346+
env_var: &'static str,
347+
default_level_filter: LevelFilter,
340348
) -> TracingBuilder<builder_state::Config> {
341349
TracingBuilder {
342350
service_name: self.service_name,
343351
console_log_config: SubscriberConfig {
344352
enabled: true,
345-
level_filter,
353+
env_var,
354+
default_level_filter,
346355
},
347356
otlp_log_config: self.otlp_log_config,
348357
otlp_trace_config: self.otlp_trace_config,
349358
_marker: self._marker,
350359
}
351360
}
352361

353-
/// Enable the OTLP logging subscriber, and filter the log level.
362+
/// Enable the OTLP logging subscriber and set the default [`LevelFilter`]
363+
/// which is overridable through the given environment variable.
354364
///
355365
/// You can configure the OTLP log exports through the variables defined
356366
/// in the opentelemetry crates. See [`Tracing`].
357367
pub fn with_otlp_log_exporter(
358368
self,
359-
level_filter: LevelFilter,
369+
env_var: &'static str,
370+
default_level_filter: LevelFilter,
360371
) -> TracingBuilder<builder_state::Config> {
361372
TracingBuilder {
362373
service_name: self.service_name,
363374
console_log_config: self.console_log_config,
364375
otlp_log_config: SubscriberConfig {
365376
enabled: true,
366-
level_filter,
377+
env_var,
378+
default_level_filter,
367379
},
368380
otlp_trace_config: self.otlp_trace_config,
369381
_marker: self._marker,
370382
}
371383
}
372384

373-
/// Enable the OTLP tracing subscriber, and filter the log level.
385+
/// Enable the OTLP tracing subscriber and set the default [`LevelFilter`]
386+
/// which is overridable through the given environment variable.
374387
///
375388
/// You can configure the OTLP trace exports through the variables defined
376389
/// in the opentelemetry crates. See [`Tracing`].
377390
pub fn with_otlp_trace_exporter(
378391
self,
379-
level_filter: LevelFilter,
392+
env_var: &'static str,
393+
default_level_filter: LevelFilter,
380394
) -> TracingBuilder<builder_state::Config> {
381395
TracingBuilder {
382396
service_name: self.service_name,
383397
console_log_config: self.console_log_config,
384398
otlp_log_config: self.otlp_log_config,
385399
otlp_trace_config: SubscriberConfig {
386400
enabled: true,
387-
level_filter,
401+
env_var,
402+
default_level_filter,
388403
},
389404
_marker: self._marker,
390405
}
@@ -406,6 +421,14 @@ impl TracingBuilder<builder_state::Config> {
406421
}
407422
}
408423

424+
/// Create an [`EnvFilter`] configured with the given environment variable and default [`Directive`].
425+
fn env_filter_builder(env_var: &str, default_directive: impl Into<Directive>) -> EnvFilter {
426+
EnvFilter::builder()
427+
.with_env_var(env_var)
428+
.with_default_directive(default_directive.into())
429+
.from_env_lossy()
430+
}
431+
409432
#[cfg(test)]
410433
mod test {
411434
use super::*;
@@ -421,15 +444,16 @@ mod test {
421444
fn builder_with_console_output() {
422445
let trace_guard = Tracing::builder()
423446
.service_name("test")
424-
.with_console_output(LevelFilter::TRACE)
425-
.with_console_output(LevelFilter::DEBUG)
447+
.with_console_output("ABC_A", LevelFilter::TRACE)
448+
.with_console_output("ABC_B", LevelFilter::DEBUG)
426449
.build();
427450

428451
assert_eq!(
429452
trace_guard.console_log_config,
430453
SubscriberConfig {
431454
enabled: true,
432-
level_filter: LevelFilter::DEBUG
455+
env_var: "ABC_B",
456+
default_level_filter: LevelFilter::DEBUG
433457
}
434458
);
435459
assert!(!trace_guard.otlp_log_config.enabled);
@@ -440,30 +464,33 @@ mod test {
440464
fn builder_with_all() {
441465
let trace_guard = Tracing::builder()
442466
.service_name("test")
443-
.with_console_output(LevelFilter::INFO)
444-
.with_otlp_log_exporter(LevelFilter::DEBUG)
445-
.with_otlp_trace_exporter(LevelFilter::TRACE)
467+
.with_console_output("ABC_CONSOLE", LevelFilter::INFO)
468+
.with_otlp_log_exporter("ABC_OTLP_LOG", LevelFilter::DEBUG)
469+
.with_otlp_trace_exporter("ABC_OTLP_TRACE", LevelFilter::TRACE)
446470
.build();
447471

448472
assert_eq!(
449473
trace_guard.console_log_config,
450474
SubscriberConfig {
451475
enabled: true,
452-
level_filter: LevelFilter::INFO
476+
env_var: "ABC_CONSOLE",
477+
default_level_filter: LevelFilter::INFO
453478
}
454479
);
455480
assert_eq!(
456481
trace_guard.otlp_log_config,
457482
SubscriberConfig {
458483
enabled: true,
459-
level_filter: LevelFilter::DEBUG
484+
env_var: "ABC_OTLP_LOG",
485+
default_level_filter: LevelFilter::DEBUG
460486
}
461487
);
462488
assert_eq!(
463489
trace_guard.otlp_trace_config,
464490
SubscriberConfig {
465491
enabled: true,
466-
level_filter: LevelFilter::TRACE
492+
env_var: "ABC_OTLP_TRACE",
493+
default_level_filter: LevelFilter::TRACE
467494
}
468495
);
469496
}

0 commit comments

Comments
 (0)