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.
Describe your environment
Labels: bug, sdk, metrics, exporter
Affected packages:
opentelemetry-sdkFound on:
main@0a5d76b6Environment: CPython 3.12
What happened?
Both histogram aggregations seed
_min/_maxwithmath.infand-math.infand never consultself._record_min_maxincollect(). 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+Infinityand maximum is-Infinity.to_jsonhas the same problem and emits the bare literalsInfinityand-Infinity, which are not valid JSON.Steps to Reproduce
Expected Result
minandmaxare absent from the data point and from the encoded OTLP message, since OTLP declares themoptional double.Actual Result
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 computingmax - mingets nonsense; and themin > maxinvariant that consumers are entitled to rely on is violated.Separately,
to_jsonproduces output that a conformant JSON parser rejects, which affectsConsoleMetricExporterand 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
+1orme too, to help us triage it. Learn more here.