use crate::service::OtelTracingService;
use opentelemetry_sdk::logs::SdkLoggerProvider;
use opentelemetry_sdk::trace::SdkTracerProvider;
use std::sync::Arc;
use std::time::Duration;
use tower::Layer;
#[derive(Clone)]
pub struct OtelTracingLayer<E> {
extractor: E,
tracer_provider: Option<Arc<SdkTracerProvider>>,
logger_provider: Option<Arc<SdkLoggerProvider>>,
flush_on_end: bool,
flush_timeout: Duration,
}
impl<E> OtelTracingLayer<E> {
pub fn new(extractor: E) -> Self {
Self {
extractor,
tracer_provider: None,
logger_provider: None,
flush_on_end: true,
flush_timeout: Duration::from_secs(5),
}
}
pub fn builder(extractor: E) -> OtelTracingLayerBuilder<E> {
OtelTracingLayerBuilder::new(extractor)
}
}
impl<S, E> Layer<S> for OtelTracingLayer<E>
where
E: Clone,
{
type Service = OtelTracingService<S, E>;
fn layer(&self, inner: S) -> Self::Service {
OtelTracingService::new(
inner,
self.extractor.clone(),
self.tracer_provider.clone(),
self.logger_provider.clone(),
self.flush_on_end,
self.flush_timeout,
)
}
}
#[must_use = "builders do nothing unless .build() is called"]
pub struct OtelTracingLayerBuilder<E> {
extractor: E,
tracer_provider: Option<Arc<SdkTracerProvider>>,
logger_provider: Option<Arc<SdkLoggerProvider>>,
flush_on_end: bool,
flush_timeout: Duration,
}
impl<E> OtelTracingLayerBuilder<E> {
pub fn new(extractor: E) -> Self {
Self {
extractor,
tracer_provider: None,
logger_provider: None,
flush_on_end: true,
flush_timeout: Duration::from_secs(5),
}
}
pub fn tracer_provider(mut self, provider: Arc<SdkTracerProvider>) -> Self {
self.tracer_provider = Some(provider);
self
}
pub fn logger_provider(mut self, provider: Arc<SdkLoggerProvider>) -> Self {
self.logger_provider = Some(provider);
self
}
pub fn flush_on_end(mut self, flush: bool) -> Self {
self.flush_on_end = flush;
self
}
pub fn flush_timeout(mut self, timeout: Duration) -> Self {
self.flush_timeout = timeout;
self
}
pub fn build(self) -> OtelTracingLayer<E> {
OtelTracingLayer {
extractor: self.extractor,
tracer_provider: self.tracer_provider,
logger_provider: self.logger_provider,
flush_on_end: self.flush_on_end,
flush_timeout: self.flush_timeout,
}
}
}