scouter_tracing/exporter/
traits.rs1use crate::error::TraceError;
2use crate::exporter::processor::BatchConfig;
3use crate::exporter::processor::EnrichSpanWithBaggageProcessor;
4use crate::exporter::scouter::ScouterSpanExporter;
5use crate::exporter::ExporterType;
6use opentelemetry_sdk::trace::BatchSpanProcessor;
7use opentelemetry_sdk::trace::Sampler;
8use opentelemetry_sdk::trace::SpanExporter;
9use opentelemetry_sdk::Resource;
10use tracing::debug;
11pub trait SpanExporterBuilder {
13 type Exporter: SpanExporter + 'static;
14
15 fn export_type(&self) -> ExporterType;
16
17 fn sample_ratio(&self) -> Option<f64>;
19
20 fn batch_export(&self) -> bool;
22
23 fn build_exporter(&self) -> Result<Self::Exporter, TraceError>;
25
26 fn to_sampler(&self) -> Sampler {
28 self.sample_ratio()
29 .map(Sampler::TraceIdRatioBased)
30 .unwrap_or(Sampler::AlwaysOn)
31 }
32
33 fn build_provider(
40 &self,
41 resource: Resource,
42 scouter_exporter: ScouterSpanExporter,
43 batch_config: Option<BatchConfig>,
44 ) -> Result<opentelemetry_sdk::trace::SdkTracerProvider, TraceError>
45 where
46 Self: Sized,
47 {
48 let exporter = self.build_exporter()?;
49
50 let use_batch = self.batch_export() || batch_config.is_some();
52 let sampler = self.to_sampler();
53
54 let mut builder = opentelemetry_sdk::trace::SdkTracerProvider::builder()
55 .with_span_processor(EnrichSpanWithBaggageProcessor);
56
57 if use_batch {
58 debug!("Using batch span processor for exporter");
59 let config = batch_config.unwrap_or_default();
60
61 let scouter_batch_processor = BatchSpanProcessor::builder(scouter_exporter)
62 .with_batch_config(config.to_otlp_config())
63 .build();
64 builder = builder.with_span_processor(scouter_batch_processor);
65
66 if self.export_type() != ExporterType::Noop {
68 let exporter_batch_processor = BatchSpanProcessor::builder(exporter)
69 .with_batch_config(config.to_otlp_config())
70 .build();
71
72 builder = builder.with_span_processor(exporter_batch_processor);
73 }
74 } else {
75 builder = builder.with_simple_exporter(scouter_exporter);
76 if self.export_type() != ExporterType::Noop {
77 builder = builder.with_simple_exporter(exporter);
78 }
79 }
80
81 builder = builder.with_sampler(sampler).with_resource(resource);
82
83 Ok(builder.build())
84 }
85}