From 9cec8a430d01d65e27014194e831c398c36114ae Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Mon, 18 Aug 2025 11:28:55 +0200 Subject: [PATCH] Switch to opentelemetry-prometheus-text-exporter --- Cargo.lock | 60 +++++++++++-------------------------- Cargo.toml | 10 ++----- crates/cli/Cargo.toml | 3 +- crates/cli/src/telemetry.rs | 59 +++++++++++++++++++----------------- deny.toml | 5 ---- 5 files changed, 51 insertions(+), 86 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9879d6b8..5079ba802 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3191,12 +3191,11 @@ dependencies = [ "opentelemetry-http", "opentelemetry-jaeger-propagator", "opentelemetry-otlp", - "opentelemetry-prometheus", + "opentelemetry-prometheus-text-exporter", "opentelemetry-resource-detectors", "opentelemetry-semantic-conventions", "opentelemetry-stdout", "opentelemetry_sdk", - "prometheus", "rand 0.8.5", "rand_chacha 0.3.1", "reqwest", @@ -4172,15 +4171,14 @@ dependencies = [ ] [[package]] -name = "opentelemetry-prometheus" -version = "0.29.1" -source = "git+https://github.com/sandhose/opentelemetry-rust.git?branch=otel-prometheus-0.30#193906c7577b4f8ee642aa771191c7d80b14a297" +name = "opentelemetry-prometheus-text-exporter" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddbb5743c13741bd9207de7c449f9797c0e513ac07551eac807da94056c530d9" dependencies = [ - "once_cell", "opentelemetry", "opentelemetry_sdk", - "prometheus", - "tracing", + "smartstring", ] [[package]] @@ -4671,21 +4669,6 @@ dependencies = [ "yansi", ] -[[package]] -name = "prometheus" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ca5326d8d0b950a9acd87e6a3f94745394f62e4dae1b1ee22b2bc0c394af43a" -dependencies = [ - "cfg-if", - "fnv", - "lazy_static", - "memchr", - "parking_lot", - "protobuf", - "thiserror 2.0.12", -] - [[package]] name = "prost" version = "0.13.5" @@ -4709,26 +4692,6 @@ dependencies = [ "syn", ] -[[package]] -name = "protobuf" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d65a1d4ddae7d8b5de68153b48f6aa3bba8cb002b243dbdbc55a5afbc98f99f4" -dependencies = [ - "once_cell", - "protobuf-support", - "thiserror 1.0.69", -] - -[[package]] -name = "protobuf-support" -version = "3.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e36c2f31e0a47f9280fb347ef5e461ffcd2c52dd520d8e216b52f93b0b0d7d6" -dependencies = [ - "thiserror 1.0.69", -] - [[package]] name = "psl" version = "2.1.128" @@ -5830,6 +5793,17 @@ dependencies = [ "serde", ] +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + [[package]] name = "socket2" version = "0.6.0" diff --git a/Cargo.toml b/Cargo.toml index b19077253..56e6388dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -407,10 +407,8 @@ version = "0.30.0" version = "0.30.0" default-features = false features = ["trace", "metrics", "http-proto"] -[workspace.dependencies.opentelemetry-prometheus] -# https://github.com/open-telemetry/opentelemetry-rust/pull/3076 -git = "https://github.com/sandhose/opentelemetry-rust.git" -branch = "otel-prometheus-0.30" +[workspace.dependencies.opentelemetry-prometheus-text-exporter] +version = "0.2.0" [workspace.dependencies.opentelemetry-resource-detectors] version = "0.9.0" [workspace.dependencies.opentelemetry-semantic-conventions] @@ -480,10 +478,6 @@ features = ["std", "pkcs5", "encryption"] [workspace.dependencies.psl] version = "2.1.128" -# Prometheus metrics -[workspace.dependencies.prometheus] -version = "0.14.0" - # High-precision clock [workspace.dependencies.quanta] version = "0.12.6" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 22def30c7..1baebd12c 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -59,12 +59,11 @@ opentelemetry.workspace = true opentelemetry-http.workspace = true opentelemetry-jaeger-propagator.workspace = true opentelemetry-otlp.workspace = true -opentelemetry-prometheus.workspace = true +opentelemetry-prometheus-text-exporter.workspace = true opentelemetry-resource-detectors.workspace = true opentelemetry-semantic-conventions.workspace = true opentelemetry-stdout.workspace = true opentelemetry_sdk.workspace = true -prometheus.workspace = true sentry.workspace = true sentry-tracing.workspace = true sentry-tower.workspace = true diff --git a/crates/cli/src/telemetry.rs b/crates/cli/src/telemetry.rs index 630dcbfca..274ae770e 100644 --- a/crates/cli/src/telemetry.rs +++ b/crates/cli/src/telemetry.rs @@ -23,7 +23,7 @@ use opentelemetry::{ trace::TracerProvider as _, }; use opentelemetry_otlp::{WithExportConfig, WithHttpConfig}; -use opentelemetry_prometheus::PrometheusExporter; +use opentelemetry_prometheus_text_exporter::PrometheusExporter; use opentelemetry_sdk::{ Resource, metrics::{ManualReader, SdkMeterProvider, periodic_reader_with_async_runtime::PeriodicReader}, @@ -33,7 +33,6 @@ use opentelemetry_sdk::{ }, }; use opentelemetry_semantic_conventions as semcov; -use prometheus::Registry; use url::Url; static SCOPE: LazyLock = LazyLock::new(|| { @@ -49,7 +48,7 @@ pub static METER: LazyLock = pub static TRACER: OnceLock = OnceLock::new(); static METER_PROVIDER: OnceLock = OnceLock::new(); static TRACER_PROVIDER: OnceLock = OnceLock::new(); -static PROMETHEUS_REGISTRY: OnceLock = OnceLock::new(); +static PROMETHEUS_EXPORTER: OnceLock = OnceLock::new(); pub fn setup(config: &TelemetryConfig) -> anyhow::Result<()> { let propagator = propagator(&config.tracing.propagators); @@ -180,21 +179,30 @@ type PromServiceFuture = #[allow(clippy::needless_pass_by_value)] fn prometheus_service_fn(_req: T) -> PromServiceFuture { - use prometheus::{Encoder, TextEncoder}; - - let response = if let Some(registry) = PROMETHEUS_REGISTRY.get() { - let mut buffer = Vec::new(); - let encoder = TextEncoder::new(); - let metric_families = registry.gather(); - - // That shouldn't panic, unless we're constructing invalid labels - encoder.encode(&metric_families, &mut buffer).unwrap(); - - Response::builder() - .status(200) - .header(CONTENT_TYPE, encoder.format_type()) - .body(Full::new(Bytes::from(buffer))) - .unwrap() + let response = if let Some(exporter) = PROMETHEUS_EXPORTER.get() { + // We'll need some space for this, so we preallocate a bit + let mut buffer = Vec::with_capacity(1024); + + if let Err(err) = exporter.export(&mut buffer) { + tracing::error!( + error = &err as &dyn std::error::Error, + "Failed to export Prometheus metrics" + ); + + Response::builder() + .status(500) + .header(CONTENT_TYPE, "text/plain") + .body(Full::new(Bytes::from_static( + b"Failed to export Prometheus metrics, see logs for details", + ))) + .unwrap() + } else { + Response::builder() + .status(200) + .header(CONTENT_TYPE, "text/plain;version=1.0.0") + .body(Full::new(Bytes::from(buffer))) + .unwrap() + } } else { Response::builder() .status(500) @@ -209,7 +217,7 @@ fn prometheus_service_fn(_req: T) -> PromServiceFuture { } pub fn prometheus_service() -> tower::util::ServiceFn PromServiceFuture> { - if PROMETHEUS_REGISTRY.get().is_none() { + if PROMETHEUS_EXPORTER.get().is_none() { tracing::warn!( "A Prometheus resource was mounted on a listener, but the Prometheus exporter was not setup in the config" ); @@ -219,16 +227,11 @@ pub fn prometheus_service() -> tower::util::ServiceFn PromServiceFut } fn prometheus_metric_reader() -> anyhow::Result { - let registry = Registry::new(); - - PROMETHEUS_REGISTRY - .set(registry.clone()) - .map_err(|_| anyhow::anyhow!("PROMETHEUS_REGISTRY was set twice"))?; + let exporter = PrometheusExporter::builder().without_scope_info().build(); - let exporter = opentelemetry_prometheus::exporter() - .with_registry(registry) - .without_scope_info() - .build()?; + PROMETHEUS_EXPORTER + .set(exporter.clone()) + .map_err(|_| anyhow::anyhow!("PROMETHEUS_EXPORTER was set twice"))?; Ok(exporter) } diff --git a/deny.toml b/deny.toml index 508816d14..0d09c790f 100644 --- a/deny.toml +++ b/deny.toml @@ -98,8 +98,3 @@ deny = ["oldtime"] unknown-registry = "warn" unknown-git = "warn" allow-registry = ["https://github.com/rust-lang/crates.io-index"] - -allow-git = [ - # https://github.com/open-telemetry/opentelemetry-rust/pull/3076 - "https://github.com/sandhose/opentelemetry-rust", -]