From 9bf6470d8e850d7efa50ca8c00deaac1cb0a18b2 Mon Sep 17 00:00:00 2001 From: Lev Zakharov Date: Tue, 29 Jul 2025 18:13:21 +0300 Subject: [PATCH] sdk/metric: use runtime.GOMAXPROCS(0) instead of runtime.NumCPU() in DefaultExemplarReservoirProviderSelector for the FixedSizeReservoirProvider default size (#7094) This PR changes `DefaultExemplarReservoirProviderSelector` in `go.opentelemetry.io/otel/sdk/metric` to use `runtime.GOMAXPROCS(0)` instead of `runtime.NumCPU()` for the `FixedSizeReservoirProvider` default size. **Motivation** The [runtime.NumCPU](https://pkg.go.dev/runtime#NumCPU) returns the number of logical CPUs usable by the current process. In Kubernetes, the method will return the total number of cores on the node, not the actual number of cores available to the container. Since it is common practice to allocate only a small fraction of the total CPU on a node to a container, the current implementation may result in an excessive `FixedSizeReservoir` size, which in turn negatively impacts the resources consumed. --------- Co-authored-by: Tyler Yahn Co-authored-by: Tyler Yahn --- CHANGELOG.md | 1 + sdk/metric/exemplar.go | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fcc8a608..4dedede95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Change `AssertEqual` in `go.opentelemetry.io/otel/log/logtest` to accept `TestingT` in order to support benchmarks and fuzz tests. (#6908) - Change `SDKProcessorLogQueueCapacity`, `SDKProcessorLogQueueSize`, `SDKProcessorSpanQueueSize`, and `SDKProcessorSpanQueueCapacity` in `go.opentelemetry.io/otel/semconv/v1.36.0/otelconv` to use a `Int64ObservableUpDownCounter`. (#7041) +- Change `DefaultExemplarReservoirProviderSelector` in `go.opentelemetry.io/otel/sdk/metric` to use `runtime.GOMAXPROCS(0)` instead of `runtime.NumCPU()` for the `FixedSizeReservoirProvider` default size. (#7094) diff --git a/sdk/metric/exemplar.go b/sdk/metric/exemplar.go index e5d212158..38b8745e6 100644 --- a/sdk/metric/exemplar.go +++ b/sdk/metric/exemplar.go @@ -66,9 +66,11 @@ func DefaultExemplarReservoirProviderSelector(agg Aggregation) exemplar.Reservoi // provided, the default size MAY be the number of possible // concurrent threads (e.g. number of CPUs) to help reduce // contention. Otherwise, a default size of 1 SHOULD be used. - n = max(runtime.NumCPU(), - // Should never be the case, but be defensive. - 1) + // + // Use runtime.GOMAXPROCS instead of runtime.NumCPU to support + // containerized environments that may have less than the total number + // of logical CPUs available on the local machine allocated to it. + n = max(runtime.GOMAXPROCS(0), 1) } return exemplar.FixedSizeReservoirProvider(n)