diff --git a/rust/libs/observability/src/observability.rs b/rust/libs/observability/src/observability.rs index 15b28b8d55..a80ab6d92a 100644 --- a/rust/libs/observability/src/observability.rs +++ b/rust/libs/observability/src/observability.rs @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -use anyhow::{Ok, Result}; +use anyhow::{Context, Ok, Result}; use opentelemetry::global::{self, shutdown_tracer_provider}; use opentelemetry_otlp::WithExportConfig; use opentelemetry_sdk::metrics::SdkMeterProvider; @@ -27,7 +27,6 @@ use crate::config::Config; pub const SERVICE_NAME: &str = opentelemetry_semantic_conventions::resource::SERVICE_NAME; pub trait Observability { - fn build(self) -> Result; fn shutdown(&mut self) -> Result<()>; } @@ -38,51 +37,43 @@ pub struct ObservabilityImpl { } impl ObservabilityImpl { - pub fn new(cfg: Config) -> ObservabilityImpl { - ObservabilityImpl { + pub fn new(cfg: Config) -> Result { + let mut obj = ObservabilityImpl { config: cfg, meter_provider: None, tracer_provider: None, - } - } - - fn config(&self) -> &Config { - &self.config - } -} + }; -impl Observability for ObservabilityImpl { - fn build(mut self) -> Result { - if !self.config.enabled { - return Ok(self); + if !obj.config.enabled { + return Ok(obj); } - if self.config.meter.enabled { + if obj.config.meter.enabled { // NOTE: Since the agent implementation does not use views, we will use the simplest implementation for the current phase. // If we want flexibility and customization, use SdkMeterProvider::builder. let provider = opentelemetry_otlp::new_pipeline() .metrics(runtime::Tokio) - .with_period(self.config.meter.export_duration) - .with_resource(Resource::from(self.config())) - .with_timeout(self.config.meter.export_timeout_duration) + .with_period(obj.config.meter.export_duration) + .with_resource(Resource::from(obj.config())) + .with_timeout(obj.config.meter.export_timeout_duration) .with_exporter( opentelemetry_otlp::new_exporter().tonic().with_endpoint( - Url::parse(self.config.endpoint.as_str())? + Url::parse(obj.config.endpoint.as_str())? .join("/v1/metrics")? .as_str(), ), ) .build()?; - self.meter_provider = Some(provider.clone()); + obj.meter_provider = Some(provider.clone()); global::set_meter_provider(provider.clone()); } - if self.config.tracer.enabled { + if obj.config.tracer.enabled { let tracer = opentelemetry_otlp::new_pipeline() .tracing() .with_exporter( opentelemetry_otlp::new_exporter().tonic().with_endpoint( - Url::parse(self.config.endpoint.as_str())? + Url::parse(obj.config.endpoint.as_str())? .join("/v1/traces")? .as_str(), ), @@ -90,16 +81,24 @@ impl Observability for ObservabilityImpl { .with_trace_config( trace::config() .with_sampler(trace::Sampler::AlwaysOn) - .with_resource(Resource::from(self.config())) + .with_resource(Resource::from(obj.config())) .with_id_generator(trace::RandomIdGenerator::default()), ) .install_batch(runtime::Tokio)?; + let provider = tracer.provider().context("failed to get provider")?; + obj.tracer_provider = Some(provider.clone()); global::set_text_map_propagator(TraceContextPropagator::new()); - global::set_tracer_provider(tracer.provider().unwrap()); + global::set_tracer_provider(provider.clone()); } - Ok(self) + Ok(obj) + } + + fn config(&self) -> &Config { + &self.config } +} +impl Observability for ObservabilityImpl { fn shutdown(&mut self) -> Result<()> { if !self.config.enabled { return Ok(());