use crate::error::TraceError;
use crate::exporter::processor::BatchConfig;
use crate::exporter::processor::EnrichSpanWithBaggageProcessor;
use crate::exporter::scouter::ScouterSpanExporter;
use crate::exporter::ExporterType;
use opentelemetry_sdk::trace::BatchSpanProcessor;
use opentelemetry_sdk::trace::Sampler;
use opentelemetry_sdk::trace::SpanExporter;
use opentelemetry_sdk::Resource;
use tracing::debug;
pub trait SpanExporterBuilder {
type Exporter: SpanExporter + 'static;
fn export_type(&self) -> ExporterType;
fn sample_ratio(&self) -> Option<f64>;
fn set_sample_ratio(&mut self, sample_ratio: Option<f64>);
fn batch_export(&self) -> bool;
fn build_exporter(&self, resource: &Resource) -> Result<Self::Exporter, TraceError>;
fn to_sampler(&self) -> Sampler {
self.sample_ratio()
.map(|ratio| {
debug!("Using TraceIdRatioBased sampler with ratio {}", ratio);
Sampler::TraceIdRatioBased(ratio)
})
.unwrap_or(Sampler::AlwaysOn)
}
fn build_provider(
&self,
resource: Resource,
scouter_exporter: ScouterSpanExporter,
batch_config: Option<BatchConfig>,
) -> Result<opentelemetry_sdk::trace::SdkTracerProvider, TraceError>
where
Self: Sized,
{
let exporter = self.build_exporter(&resource)?;
let use_batch = self.batch_export() || batch_config.is_some();
let sampler = self.to_sampler();
let mut builder = opentelemetry_sdk::trace::SdkTracerProvider::builder()
.with_span_processor(EnrichSpanWithBaggageProcessor);
if use_batch {
debug!("Using batch span processor for exporter");
let config = batch_config.unwrap_or_default();
let scouter_batch_processor = BatchSpanProcessor::builder(scouter_exporter)
.with_batch_config(config.to_otlp_config())
.build();
builder = builder.with_span_processor(scouter_batch_processor);
if self.export_type() != ExporterType::Noop {
let exporter_batch_processor = BatchSpanProcessor::builder(exporter)
.with_batch_config(config.to_otlp_config())
.build();
builder = builder.with_span_processor(exporter_batch_processor);
}
} else {
builder = builder.with_simple_exporter(scouter_exporter);
if self.export_type() != ExporterType::Noop {
builder = builder.with_simple_exporter(exporter);
}
}
builder = builder.with_sampler(sampler).with_resource(resource);
Ok(builder.build())
}
}