use opentelemetry::{global, trace::TracerProvider as _};
use opentelemetry_sdk::trace::Config;
use opentelemetry_sdk::{runtime, trace::TracerProvider};
use tracing_core::Subscriber;
use tracing_subscriber::{registry::LookupSpan, Layer};
use super::exporters::XrayExporterBuilder;
use crate::layers::TelemetryLayerBuilder;
#[derive(Debug, Default)]
pub struct TraceOptions {
config: Option<Config>,
}
impl TraceOptions {
pub fn with_trace_config(config: Config) -> Self {
TraceOptions {
config: Some(config),
}
}
}
#[derive(Debug)]
pub enum LayerBuilder {
Stdout(TraceOptions),
Xray(TraceOptions),
}
impl TelemetryLayerBuilder for LayerBuilder {
async fn layer<S>(self) -> Result<Box<dyn Layer<S> + Send + Sync + 'static>, String>
where
S: Subscriber + Send + Sync,
for<'a> S: LookupSpan<'a>,
{
let provider = match self {
LayerBuilder::Stdout(TraceOptions { config }) => {
let exporter = opentelemetry_stdout::SpanExporter::default();
let provider = TracerProvider::builder()
.with_config(config.unwrap_or_default())
.with_batch_exporter(exporter, runtime::Tokio)
.build();
Ok(provider)
}
LayerBuilder::Xray(TraceOptions { config }) => {
XrayExporterBuilder::with_default_config()
.await
.build_span_exporter()
.map(|exporter| {
TracerProvider::builder()
.with_config(config.unwrap_or_default())
.with_batch_exporter(exporter, runtime::Tokio)
.build()
})
.map_err(|error| error.to_string())
}
}?;
let tracer = provider.tracer("metry-tracer");
let _ = global::set_tracer_provider(provider);
let trace_layer = tracing_opentelemetry::layer().with_tracer(tracer);
Ok(Box::new(trace_layer))
}
}