open-telemetry / open-telemetry/opentelemetry-python

record_min_max=False exports histogram min=+Infinity and max=-Infinity

Open
#5,570 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
2.6k
Forks
1k
Avg merge
4d 15h
Merged PRs (30d)
19

Description

Describe your environment

Labels: bug, sdk, metrics, exporter
Affected packages: opentelemetry-sdk
Found on: main @ 0a5d76b6
Environment: CPython 3.12

What happened?

Both histogram aggregations seed _min/_max with math.inf and -math.inf and never consult self._record_min_max in collect(). With min/max recording disabled the sentinels are handed straight to the data point, and the OTLP encoder sets both optional fields as present - so a backend receives a histogram whose minimum is +Infinity and maximum is -Infinity.

to_json has the same problem and emits the bare literals Infinity and -Infinity, which are not valid JSON.

Steps to Reproduce
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import InMemoryMetricReader
from opentelemetry.sdk.metrics.view import ExplicitBucketHistogramAggregation, View

reader = InMemoryMetricReader()
provider = MeterProvider(
    metric_readers=[reader],
    views=[View(instrument_name="hist",
                aggregation=ExplicitBucketHistogramAggregation(record_min_max=False))],
)
histogram = provider.get_meter("m").create_histogram("hist")
histogram.record(5)
histogram.record(50)

point = reader.get_metrics_data().resource_metrics[0].scope_metrics[0].metrics[0].data.data_points[0]
print(point.min, point.max)
print(point.to_json())
Expected Result

min and max are absent from the data point and from the encoded OTLP message, since OTLP declares them optional double.

Actual Result
--- ExplicitBucketHistogram(record_min_max=False) ---
  SDK data point : min=inf  max=-inf  sum=55  count=2
  OTLP protobuf  : HasField(min)=True min=inf   HasField(max)=True max=-inf
--- ExponentialBucketHistogram(record_min_max=False) ---
  OTLP protobuf  : HasField(min)=True min=inf   HasField(max)=True max=-inf

# to_json, parsed by a strict RFC 8259 reader
to_json() emits: "min": Infinity, "max": -Infinity
strict JSON parse: non-JSON constant 'Infinity'

# and the data-model invariant is violated outright
min=inf  max=-inf  ->  min > max
Additional context

Corrupt histogram data for anyone who disables min/max recording - a reasonable thing to do, since it is exactly the knob you reach for to cut per-series cost. A backend charting minimum latency reads +Infinity; anything computing max - min gets nonsense; and the min > max invariant that consumers are entitled to rely on is violated.

Separately, to_json produces output that a conformant JSON parser rejects, which affects ConsoleMetricExporter and anything else built on the SDK's own serialisation.

Would you like to implement a fix?

Yes

Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with ExplicitBucketHistogramAggregation and ExponentialBucketHistogram, then trace collect(), the OTLP encoding path, and to_json(). Reproduce the case with InMemoryMetricReader and record_min_max=False. Done means min and max are absent when disabled, the OTLP optional fields are unset, and to_json() is accepted by a strict JSON parser.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
observability
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.