diff --git a/src/config.rs b/src/config.rs index c5b3ff8..48c8619 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,6 +10,7 @@ use std::collections::{BTreeMap as Map, HashMap}; use famedly_rust_utils::LevelFilter; use serde::Deserialize; +use tracing_subscriber::EnvFilter; use url::Url; /// Default gRPC Otel endpoint @@ -126,27 +127,21 @@ pub struct ProviderConfig { impl ProviderConfig { /// Builds a trace filter - pub(crate) fn get_filter(&self, crate_name: &'static str) -> String { - format!( - "{},{}{}={}", - self.general_level, - build_dependencies_level_string(&self.dependencies_levels), - crate_name, - self.level - ) + pub(crate) fn get_filter( + &self, + crate_name: &'static str, + ) -> Result { + filter_from_config(self.general_level, &self.dependencies_levels, crate_name, self.level) } } impl StdoutLogsConfig { /// Builds a trace filter - pub(crate) fn get_filter(&self, crate_name: &'static str) -> String { - format!( - "{},{}{}={}", - self.general_level, - build_dependencies_level_string(&self.dependencies_levels), - crate_name, - self.level - ) + pub(crate) fn get_filter( + &self, + crate_name: &'static str, + ) -> Result { + filter_from_config(self.general_level, &self.dependencies_levels, crate_name, self.level) } } @@ -183,13 +178,17 @@ const fn true_() -> bool { true } -/// Builds a string that configures the filter level of each dependency on the -/// map -fn build_dependencies_level_string(dependencies_levels: &HashMap) -> String { - let mut dependencies_levels = - dependencies_levels.iter().map(|(k, v)| format!("{k}={v}")).collect::>().join(","); - if !dependencies_levels.is_empty() { - dependencies_levels.push(','); +/// Given options for a series of dependencies, build a trace filter +fn filter_from_config( + general_level: LevelFilter, + dependencies_levels: &HashMap, + crate_name: &'static str, + level: LevelFilter, +) -> Result { + let mut filter = EnvFilter::new(general_level.to_string()); + for (target, level_filter) in dependencies_levels { + filter = filter.add_directive(format!("{target}={level_filter}").parse()?); } - dependencies_levels + filter = filter.add_directive(format!("{crate_name}={}", level).parse()?); + Ok(filter) } diff --git a/src/lib.rs b/src/lib.rs index f2d1a45..b568176 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //! Lib containing the definitions and initializations of the OpenTelemetry //! tools #![cfg_attr(all(doc, not(doctest)), feature(doc_auto_cfg))] -use std::{collections::BTreeMap as Map, str::FromStr as _}; +use std::collections::BTreeMap as Map; use config::{OtelConfig, OtelUrl, StdoutLogsConfig}; use opentelemetry::{KeyValue, trace::TracerProvider as _}; @@ -23,9 +23,7 @@ use opentelemetry_sdk::{ }; use opentelemetry_semantic_conventions::resource::SERVICE_VERSION; use tracing_opentelemetry::{MetricsLayer, OpenTelemetryLayer}; -use tracing_subscriber::{ - EnvFilter, Layer, layer::SubscriberExt as _, util::SubscriberInitExt as _, -}; +use tracing_subscriber::{Layer, layer::SubscriberExt as _, util::SubscriberInitExt as _}; #[cfg(feature = "axum")] pub mod axum; @@ -155,7 +153,7 @@ pub fn init_otel( .or(Some(&StdoutLogsConfig::default())) .and_then(|stdout| stdout.enabled.then_some(stdout)) .map(|logger_config| { - let filter_fmt = EnvFilter::from_str(&logger_config.get_filter(main_crate))?; + let filter_fmt = logger_config.get_filter(main_crate)?; let stdout_layer = tracing_subscriber::fmt::layer().with_thread_names(true); Ok::<_, OtelInitError>( if logger_config.json_output { @@ -176,7 +174,7 @@ pub fn init_otel( .as_ref() .and_then(|(exporter, resource)| { exporter.logs.as_ref().and_then(|c| c.enabled.then_some(c)).map(|logger_config| { - let filter_otel = EnvFilter::from_str(&logger_config.get_filter(main_crate))?; + let filter_otel = logger_config.get_filter(main_crate)?; let logger_provider = init_logs(exporter.endpoint.clone(), resource.clone())?; // Create a new OpenTelemetryTracingBridge using the above LoggerProvider. @@ -193,7 +191,7 @@ pub fn init_otel( .as_ref() .and_then(|(exporter, resource)| { exporter.traces.as_ref().and_then(|c| c.enabled.then_some(c)).map(|tracer_config| { - let trace_filter = EnvFilter::from_str(&tracer_config.get_filter(main_crate))?; + let trace_filter = tracer_config.get_filter(main_crate)?; let tracer_provider = init_traces(exporter.endpoint.clone(), resource.clone())?; let tracer = tracer_provider.tracer(service_name); let tracer_layer = OpenTelemetryLayer::new(tracer).with_filter(trace_filter); @@ -207,7 +205,7 @@ pub fn init_otel( .as_ref() .and_then(|(exporter, resource)| { exporter.metrics.as_ref().and_then(|c| c.enabled.then_some(c)).map(|meter_config| { - let metrics_filter = EnvFilter::from_str(&meter_config.get_filter(main_crate))?; + let metrics_filter = meter_config.get_filter(main_crate)?; let meter_provider = init_metrics(exporter.endpoint.clone(), resource.clone())?; let meter_layer = MetricsLayer::new(meter_provider.clone()).with_filter(metrics_filter);