Honor the OTLP metrics temporality preference (#51220)

## Why

Some metrics backends require cumulative metrics, while configured OTLP exporters previously always used delta temporality.

## What changed

Read `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` for configured HTTP and gRPC metrics exporters. Accept `delta`, `cumulative`, and `lowmemory` case-insensitively, retaining delta for unset, empty, or unrecognized values. Document the setting and preserve existing temporality for the built-in Statsig exporter and runtime snapshots.

## Testing

Update the HTTP loopback test to set the preference in an isolated subprocess and assert that the exported counter uses cumulative aggregation temporality.

GitOrigin-RevId: ca212eea20054b947005d323186c8b9a819ace9d
This commit is contained in:
daniel-oai
2026-10-06 01:36:17 +00:00
committed by copyberry
parent 4171362e44
commit 28b91c7c31
3 changed files with 67 additions and 2 deletions
+20 -1
View File
@@ -363,10 +363,16 @@ impl MetricsClient {
build_provider(resource, exporter, export_interval, runtime_reader.clone())
}
MetricsExporter::Otlp(exporter) => {
let temporality = otlp_metrics_temporality(
&exporter,
std::env::var("OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE")
.ok()
.as_deref(),
);
let exporter = crate::network_policy::PolicyExporter {
exporter: build_otlp_metric_exporter(
exporter,
Temporality::Delta,
temporality,
&http_client_factory,
)?,
policy: http_client_factory.network_policy().clone(),
@@ -589,6 +595,19 @@ where
(provider, meter)
}
fn otlp_metrics_temporality(exporter: &OtelExporter, preference: Option<&str>) -> Temporality {
// Select before resolving Statsig to OTLP so its built-in route stays Delta.
match exporter {
OtelExporter::None | OtelExporter::Statsig => Temporality::Delta,
OtelExporter::OtlpGrpc { .. } | OtelExporter::OtlpHttp { .. } => match preference {
Some(value) if value.eq_ignore_ascii_case("cumulative") => Temporality::Cumulative,
Some(value) if value.eq_ignore_ascii_case("lowmemory") => Temporality::LowMemory,
// Preserve Codex's existing default for unset, empty, or unknown values.
_ => Temporality::Delta,
},
}
}
fn build_otlp_metric_exporter(
exporter: OtelExporter,
temporality: Temporality,