From 04c80849439dbf70ef2339192578621cf839725a Mon Sep 17 00:00:00 2001 From: Sharang Parnerkar Date: Sun, 8 Mar 2026 17:01:02 +0100 Subject: [PATCH] Switch OTLP exporter from gRPC/tonic to HTTP/reqwest gRPC requires special reverse proxy config for HTTP/2. HTTP works behind standard HTTPS proxies like Traefik/Caddy on port 4318. Co-Authored-By: Claude Opus 4.6 --- compliance-core/Cargo.toml | 2 +- compliance-core/src/telemetry.rs | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/compliance-core/Cargo.toml b/compliance-core/Cargo.toml index ed283e5..197ad46 100644 --- a/compliance-core/Cargo.toml +++ b/compliance-core/Cargo.toml @@ -32,7 +32,7 @@ bson = { version = "2", features = ["chrono-0_4"] } mongodb = { workspace = true, optional = true } opentelemetry = { version = "0.29", optional = true } opentelemetry_sdk = { version = "0.29", features = ["rt-tokio"], optional = true } -opentelemetry-otlp = { version = "0.29", features = ["grpc-tonic"], optional = true } +opentelemetry-otlp = { version = "0.29", features = ["http", "reqwest-client"], optional = true } opentelemetry-appender-tracing = { version = "0.29", optional = true } tracing-opentelemetry = { version = "0.30", optional = true } tracing-subscriber = { workspace = true, optional = true } diff --git a/compliance-core/src/telemetry.rs b/compliance-core/src/telemetry.rs index 7649820..5e933fc 100644 --- a/compliance-core/src/telemetry.rs +++ b/compliance-core/src/telemetry.rs @@ -1,6 +1,6 @@ //! OpenTelemetry initialization for traces and logs. //! -//! Exports traces and logs via OTLP (gRPC) when `OTEL_EXPORTER_OTLP_ENDPOINT` +//! Exports traces and logs via OTLP/HTTP when `OTEL_EXPORTER_OTLP_ENDPOINT` //! is set. Always includes a `tracing_subscriber::fmt` layer for console output. //! //! Compatible with SigNoz, Grafana Tempo/Loki, Jaeger, and any OTLP-compatible @@ -10,7 +10,7 @@ //! //! | Variable | Description | Default | //! |---|---|---| -//! | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint (e.g. `http://localhost:4317`) | *(disabled)* | +//! | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint (e.g. `https://otel.example.com`) | *(disabled)* | //! | `OTEL_SERVICE_NAME` | Service name for resource | `service_name` param | //! | `RUST_LOG` / standard `EnvFilter` | Log level filter | `info` | @@ -58,7 +58,7 @@ fn build_resource(service_name: &str) -> Resource { /// Initialize telemetry (tracing + logging). /// /// If `OTEL_EXPORTER_OTLP_ENDPOINT` is set, traces and logs are exported -/// via OTLP/gRPC. Console fmt output is always enabled. +/// via OTLP/HTTP. Console fmt output is always enabled. /// /// Returns a [`TelemetryGuard`] that must be held alive for the application /// lifetime. Dropping it triggers a graceful shutdown of OTel providers. @@ -76,11 +76,14 @@ pub fn init_telemetry(service_name: &str) -> TelemetryGuard { Some(ref endpoint) => { let resource = build_resource(service_name); + let traces_endpoint = format!("{endpoint}/v1/traces"); + let logs_endpoint = format!("{endpoint}/v1/logs"); + // Traces #[allow(clippy::expect_used)] let span_exporter = SpanExporter::builder() - .with_tonic() - .with_endpoint(endpoint) + .with_http() + .with_endpoint(&traces_endpoint) .build() .expect("failed to create OTLP span exporter"); @@ -96,8 +99,8 @@ pub fn init_telemetry(service_name: &str) -> TelemetryGuard { // Logs #[allow(clippy::expect_used)] let log_exporter = LogExporter::builder() - .with_tonic() - .with_endpoint(endpoint) + .with_http() + .with_endpoint(&logs_endpoint) .build() .expect("failed to create OTLP log exporter"); @@ -111,7 +114,6 @@ pub fn init_telemetry(service_name: &str) -> TelemetryGuard { // Filter to prevent telemetry-induced-telemetry loops let otel_filter = EnvFilter::new("info") .add_directive("hyper=off".parse().unwrap_or_default()) - .add_directive("tonic=off".parse().unwrap_or_default()) .add_directive("h2=off".parse().unwrap_or_default()) .add_directive("reqwest=off".parse().unwrap_or_default()); @@ -125,7 +127,7 @@ pub fn init_telemetry(service_name: &str) -> TelemetryGuard { tracing::info!( endpoint = endpoint.as_str(), service = service_name, - "OpenTelemetry OTLP export enabled" + "OpenTelemetry OTLP/HTTP export enabled" ); TelemetryGuard {