Skip to content

Commit 7620b3e

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

File tree

2 files changed

+61
-45
lines changed

2 files changed

+61
-45
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: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,29 @@ use std::sync::{LazyLock, OnceLock};
1111
use anyhow::Context as _;
1212
use bytes::Bytes;
1313
use http_body_util::Full;
14-
use hyper::{Response, header::CONTENT_TYPE};
14+
use hyper::{header::CONTENT_TYPE, Response};
1515
use mas_config::{
1616
MetricsConfig, MetricsExporterKind, Propagator, TelemetryConfig, TracingConfig,
1717
TracingExporterKind,
1818
};
1919
use opentelemetry::{
20-
InstrumentationScope, KeyValue,
2120
metrics::Meter,
2221
propagation::{TextMapCompositePropagator, TextMapPropagator},
2322
trace::TracerProvider as _,
23+
InstrumentationScope, KeyValue,
2424
};
2525
use opentelemetry_otlp::{WithExportConfig, WithHttpConfig};
2626
use opentelemetry_prometheus_text_exporter::PrometheusExporter;
2727
use opentelemetry_sdk::{
28-
Resource,
29-
metrics::{ManualReader, SdkMeterProvider, periodic_reader_with_async_runtime::PeriodicReader},
28+
metrics::{periodic_reader_with_async_runtime::PeriodicReader, ManualReader, SdkMeterProvider},
3029
propagation::{BaggagePropagator, TraceContextPropagator},
3130
trace::{
32-
Sampler, SdkTracerProvider, Tracer, span_processor_with_async_runtime::BatchSpanProcessor,
31+
span_processor_with_async_runtime::BatchSpanProcessor, IdGenerator, Sampler,
32+
SdkTracerProvider, Tracer,
3333
},
34+
Resource,
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,64 @@ 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();
130-
131-
Ok(tracer_provider)
132-
}
121+
.with_sampler(sampler);
133122

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+
.build(),
127+
128+
TracingExporterKind::Stdout => {
129+
let exporter = opentelemetry_stdout::SpanExporter::default();
130+
tracer_provider_builder
131+
.with_simple_exporter(exporter)
132+
.build()
133+
}
134+
135+
TracingExporterKind::Otlp => {
136+
let mut exporter = opentelemetry_otlp::SpanExporter::builder()
137+
.with_http()
138+
.with_http_client(mas_http::reqwest_client());
139+
if let Some(endpoint) = &config.endpoint {
140+
exporter = exporter.with_endpoint(endpoint.as_str());
141+
}
142+
let exporter = exporter
143+
.build()
144+
.context("Failed to configure OTLP trace exporter")?;
145+
146+
let batch_processor =
147+
BatchSpanProcessor::builder(exporter, opentelemetry_sdk::runtime::Tokio).build();
148+
149+
tracer_provider_builder
150+
.with_span_processor(batch_processor)
151+
.build()
152+
}
140153
};
154+
141155
TRACER_PROVIDER
142156
.set(tracer_provider.clone())
143157
.map_err(|_| anyhow::anyhow!("TRACER_PROVIDER was set twice"))?;

0 commit comments

Comments
 (0)