Skip to content
Clone
main
110 lines 3.0 KB Rust
use opentelemetry::global;
use opentelemetry_sdk::logs::SdkLoggerProvider;
use opentelemetry_sdk::metrics::SdkMeterProvider;
use opentelemetry_sdk::trace::SdkTracerProvider;
use super::config::TelemetryConfig;
use super::error::TelemetryError;
use super::{logs, metrics, propagation, resource, subscriber, traces};
#[derive(Debug, Clone)]
pub struct Telemetry {
tracer_provider: SdkTracerProvider,
meter_provider: SdkMeterProvider,
logger_provider: SdkLoggerProvider,
warnings: Vec<String>,
}
impl Telemetry {
pub fn tracer_provider(&self) -> &SdkTracerProvider {
&self.tracer_provider
}
pub fn meter_provider(&self) -> &SdkMeterProvider {
&self.meter_provider
}
pub fn logger_provider(&self) -> &SdkLoggerProvider {
&self.logger_provider
}
pub fn warnings(&self) -> &[String] {
&self.warnings
}
pub fn force_flush(&self) -> Result<(), TelemetryError> {
first_error([
self.tracer_provider
.force_flush()
.map_err(TelemetryError::exporter),
self.meter_provider
.force_flush()
.map_err(TelemetryError::exporter),
self.logger_provider
.force_flush()
.map_err(TelemetryError::exporter),
])
}
pub fn shutdown(&self) -> Result<(), TelemetryError> {
first_error([
self.tracer_provider
.shutdown()
.map_err(TelemetryError::shutdown),
self.meter_provider
.shutdown()
.map_err(TelemetryError::shutdown),
self.logger_provider
.shutdown()
.map_err(TelemetryError::shutdown),
])
}
pub fn guard(&self) -> TelemetryGuard<'_> {
TelemetryGuard { telemetry: self }
}
}
pub struct TelemetryGuard<'a> {
telemetry: &'a Telemetry,
}
impl Drop for TelemetryGuard<'_> {
fn drop(&mut self) {
if let Err(error) = self.telemetry.shutdown() {
tracing::warn!(%error, "flushing telemetry failed");
}
}
}
fn first_error(errors: [Result<(), TelemetryError>; 3]) -> Result<(), TelemetryError> {
match errors.into_iter().find(Result::is_err) {
Some(error) => error,
None => Ok(()),
}
}
pub fn install(config: &TelemetryConfig) -> Telemetry {
let resource = resource::build(config);
let mut warnings = Vec::new();
let tracer_provider = traces::build(config, resource.clone(), &mut warnings);
let meter_provider = metrics::build(config, resource.clone(), &mut warnings);
let logger_provider = logs::build(config, resource, &mut warnings);
global::set_tracer_provider(tracer_provider.clone());
global::set_meter_provider(meter_provider.clone());
propagation::install();
Telemetry {
tracer_provider,
meter_provider,
logger_provider,
warnings,
}
}
pub fn init(config: &TelemetryConfig) -> Telemetry {
let telemetry = install(config);
subscriber::install(config, &telemetry);
telemetry
}