Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 17 additions & 43 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 2 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -480,10 +478,6 @@ features = ["std", "pkcs5", "encryption"]
[workspace.dependencies.psl]
version = "2.1.141"

# Prometheus metrics
[workspace.dependencies.prometheus]
version = "0.14.0"

# High-precision clock
[workspace.dependencies.quanta]
version = "0.12.6"
Expand Down
3 changes: 1 addition & 2 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
59 changes: 31 additions & 28 deletions crates/cli/src/telemetry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand All @@ -33,7 +33,6 @@ use opentelemetry_sdk::{
},
};
use opentelemetry_semantic_conventions as semcov;
use prometheus::Registry;
use url::Url;

static SCOPE: LazyLock<InstrumentationScope> = LazyLock::new(|| {
Expand All @@ -49,7 +48,7 @@ pub static METER: LazyLock<Meter> =
pub static TRACER: OnceLock<Tracer> = OnceLock::new();
static METER_PROVIDER: OnceLock<SdkMeterProvider> = OnceLock::new();
static TRACER_PROVIDER: OnceLock<SdkTracerProvider> = OnceLock::new();
static PROMETHEUS_REGISTRY: OnceLock<Registry> = OnceLock::new();
static PROMETHEUS_EXPORTER: OnceLock<PrometheusExporter> = OnceLock::new();

pub fn setup(config: &TelemetryConfig) -> anyhow::Result<()> {
let propagator = propagator(&config.tracing.propagators);
Expand Down Expand Up @@ -180,21 +179,30 @@ type PromServiceFuture =

#[allow(clippy::needless_pass_by_value)]
fn prometheus_service_fn<T>(_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)
Expand All @@ -209,7 +217,7 @@ fn prometheus_service_fn<T>(_req: T) -> PromServiceFuture {
}

pub fn prometheus_service<T>() -> tower::util::ServiceFn<fn(T) -> 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"
);
Expand All @@ -219,16 +227,11 @@ pub fn prometheus_service<T>() -> tower::util::ServiceFn<fn(T) -> PromServiceFut
}

fn prometheus_metric_reader() -> anyhow::Result<PrometheusExporter> {
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)
}
Expand Down
5 changes: 0 additions & 5 deletions deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
]
Loading