Skip to content

Commit f0ac252

Browse files
committed
Always initialize OpenTelemetry even if no exporter is configured
1 parent be707c9 commit f0ac252

File tree

2 files changed

+58
-41
lines changed

2 files changed

+58
-41
lines changed

crates/cli/src/main.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,14 @@ async fn try_main() -> anyhow::Result<ExitCode> {
149149
// Setup OpenTelemetry tracing and metrics
150150
self::telemetry::setup(&telemetry_config).context("failed to setup OpenTelemetry")?;
151151

152-
let telemetry_layer = self::telemetry::TRACER.get().map(|tracer| {
153-
tracing_opentelemetry::layer()
154-
.with_tracer(tracer.clone())
155-
.with_tracked_inactivity(false)
156-
.with_filter(LevelFilter::INFO)
157-
});
152+
let tracer = self::telemetry::TRACER
153+
.get()
154+
.context("TRACER was not set")?;
155+
156+
let telemetry_layer = tracing_opentelemetry::layer()
157+
.with_tracer(tracer.clone())
158+
.with_tracked_inactivity(false)
159+
.with_filter(LevelFilter::INFO);
158160

159161
let subscriber = Registry::default()
160162
.with(suppress_layer)

crates/cli/src/telemetry.rs

Lines changed: 50 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ use opentelemetry_sdk::{
2929
metrics::{ManualReader, SdkMeterProvider, periodic_reader_with_async_runtime::PeriodicReader},
3030
propagation::{BaggagePropagator, TraceContextPropagator},
3131
trace::{
32-
Sampler, SdkTracerProvider, Tracer, span_processor_with_async_runtime::BatchSpanProcessor,
32+
IdGenerator, Sampler, SdkTracerProvider, Tracer,
33+
span_processor_with_async_runtime::BatchSpanProcessor,
3334
},
3435
};
3536
use opentelemetry_semantic_conventions as semcov;
36-
use url::Url;
3737

3838
static SCOPE: LazyLock<InstrumentationScope> = LazyLock::new(|| {
3939
InstrumentationScope::builder(env!("CARGO_PKG_NAME"))
@@ -94,50 +94,65 @@ fn propagator(propagators: &[Propagator]) -> TextMapCompositePropagator {
9494
TextMapCompositePropagator::new(propagators)
9595
}
9696

97-
fn stdout_tracer_provider() -> SdkTracerProvider {
98-
let exporter = opentelemetry_stdout::SpanExporter::default();
99-
SdkTracerProvider::builder()
100-
.with_simple_exporter(exporter)
101-
.build()
102-
}
103-
104-
fn otlp_tracer_provider(
105-
endpoint: Option<&Url>,
106-
sample_rate: f64,
107-
) -> anyhow::Result<SdkTracerProvider> {
108-
let mut exporter = opentelemetry_otlp::SpanExporter::builder()
109-
.with_http()
110-
.with_http_client(mas_http::reqwest_client());
111-
if let Some(endpoint) = endpoint {
112-
exporter = exporter.with_endpoint(endpoint.to_string());
97+
/// An [`IdGenerator`] which always returns an invalid trace ID and span ID
98+
///
99+
/// This is used when no exporter is being used, so that we don't log the trace
100+
/// ID when we're not tracing.
101+
#[derive(Debug, Clone, Copy)]
102+
struct InvalidIdGenerator;
103+
impl IdGenerator for InvalidIdGenerator {
104+
fn new_trace_id(&self) -> opentelemetry::TraceId {
105+
opentelemetry::TraceId::INVALID
113106
}
114-
let exporter = exporter
115-
.build()
116-
.context("Failed to configure OTLP trace exporter")?;
107+
fn new_span_id(&self) -> opentelemetry::SpanId {
108+
opentelemetry::SpanId::INVALID
109+
}
110+
}
117111

118-
let batch_processor =
119-
BatchSpanProcessor::builder(exporter, opentelemetry_sdk::runtime::Tokio).build();
112+
fn init_tracer(config: &TracingConfig) -> anyhow::Result<()> {
113+
let sample_rate = config.sample_rate.unwrap_or(1.0);
120114

121115
// We sample traces based on the parent if we have one, and if not, we
122116
// sample a ratio based on the configured sample rate
123117
let sampler = Sampler::ParentBased(Box::new(Sampler::TraceIdRatioBased(sample_rate)));
124118

125-
let tracer_provider = SdkTracerProvider::builder()
126-
.with_span_processor(batch_processor)
119+
let tracer_provider_builder = SdkTracerProvider::builder()
127120
.with_resource(resource())
128-
.with_sampler(sampler)
129-
.build();
121+
.with_sampler(sampler);
130122

131-
Ok(tracer_provider)
132-
}
133-
134-
fn init_tracer(config: &TracingConfig) -> anyhow::Result<()> {
135-
let sample_rate = config.sample_rate.unwrap_or(1.0);
136123
let tracer_provider = match config.exporter {
137-
TracingExporterKind::None => return Ok(()),
138-
TracingExporterKind::Stdout => stdout_tracer_provider(),
139-
TracingExporterKind::Otlp => otlp_tracer_provider(config.endpoint.as_ref(), sample_rate)?,
124+
TracingExporterKind::None => tracer_provider_builder
125+
.with_id_generator(InvalidIdGenerator)
126+
.with_sampler(Sampler::AlwaysOff)
127+
.build(),
128+
129+
TracingExporterKind::Stdout => {
130+
let exporter = opentelemetry_stdout::SpanExporter::default();
131+
tracer_provider_builder
132+
.with_simple_exporter(exporter)
133+
.build()
134+
}
135+
136+
TracingExporterKind::Otlp => {
137+
let mut exporter = opentelemetry_otlp::SpanExporter::builder()
138+
.with_http()
139+
.with_http_client(mas_http::reqwest_client());
140+
if let Some(endpoint) = &config.endpoint {
141+
exporter = exporter.with_endpoint(endpoint.as_str());
142+
}
143+
let exporter = exporter
144+
.build()
145+
.context("Failed to configure OTLP trace exporter")?;
146+
147+
let batch_processor =
148+
BatchSpanProcessor::builder(exporter, opentelemetry_sdk::runtime::Tokio).build();
149+
150+
tracer_provider_builder
151+
.with_span_processor(batch_processor)
152+
.build()
153+
}
140154
};
155+
141156
TRACER_PROVIDER
142157
.set(tracer_provider.clone())
143158
.map_err(|_| anyhow::anyhow!("TRACER_PROVIDER was set twice"))?;

0 commit comments

Comments
 (0)