Skip to content

Commit ee2a0f4

Browse files
lzchenocelotl
andauthored
Include min/max information in Histogram point (#2581)
* hist * changelog * tests * agg Co-authored-by: Diego Hurtado <[email protected]>
1 parent cb60b54 commit ee2a0f4

File tree

7 files changed

+115
-65
lines changed

7 files changed

+115
-65
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3030
([#2547](https://github.com/open-telemetry/opentelemetry-python/pull/2547))
3131
- Update otlp-proto-grpc and otlp-proto-http exporters to have more lax requirements for `backoff` lib
3232
([#2575](https://github.com/open-telemetry/opentelemetry-python/pull/2575))
33+
- Add min/max to histogram point
34+
([#2581](https://github.com/open-telemetry/opentelemetry-python/pull/2581))
3335

3436
## [1.10.0-0.29b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.10.0-0.29b0) - 2022-03-10
3537

exporter/opentelemetry-exporter-otlp-proto-grpc/tests/metrics/test_otlp_metrics_exporter.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,14 @@ def setUp(self):
117117
"histogram": _generate_metric(
118118
"histogram",
119119
Histogram(
120-
time_unix_nano=1641946016139533244,
121-
start_time_unix_nano=1641946016139533244,
120+
aggregation_temporality=AggregationTemporality.DELTA,
122121
bucket_counts=[1, 4],
123-
sum=67,
124122
explicit_bounds=[10.0, 20.0],
125-
aggregation_temporality=AggregationTemporality.DELTA,
123+
max=18,
124+
min=8,
125+
start_time_unix_nano=1641946016139533244,
126+
sum=67,
127+
time_unix_nano=1641946016139533244,
126128
),
127129
),
128130
}

exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ def test_histogram_to_prometheus(self):
6060
record = _generate_metric(
6161
"test@name",
6262
Histogram(
63-
time_unix_nano=1641946016139533244,
64-
start_time_unix_nano=1641946016139533244,
63+
aggregation_temporality=AggregationTemporality.CUMULATIVE,
6564
bucket_counts=[1, 3, 2],
66-
sum=579.0,
6765
explicit_bounds=[123.0, 456.0],
68-
aggregation_temporality=AggregationTemporality.CUMULATIVE,
66+
start_time_unix_nano=1641946016139533244,
67+
max=457,
68+
min=1,
69+
sum=579.0,
70+
time_unix_nano=1641946016139533244,
6971
),
7072
attributes={"histo": 1},
7173
)

opentelemetry-sdk/src/opentelemetry/sdk/_metrics/aggregation.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,18 +267,24 @@ def collect(self) -> HistogramPoint:
267267
value = self._bucket_counts
268268
start_time_unix_nano = self._start_time_unix_nano
269269
histogram_sum = self._sum
270+
histogram_max = self._max
271+
histogram_min = self._min
270272

271273
self._bucket_counts = self._get_empty_bucket_counts()
272274
self._start_time_unix_nano = now + 1
273275
self._sum = 0
276+
self._min = inf
277+
self._max = -inf
274278

275279
return HistogramPoint(
276-
start_time_unix_nano=start_time_unix_nano,
277-
time_unix_nano=now,
280+
aggregation_temporality=AggregationTemporality.DELTA,
278281
bucket_counts=tuple(value),
279282
explicit_bounds=self._boundaries,
280-
aggregation_temporality=AggregationTemporality.DELTA,
283+
max=histogram_max,
284+
min=histogram_min,
285+
start_time_unix_nano=start_time_unix_nano,
281286
sum=histogram_sum,
287+
time_unix_nano=now,
282288
)
283289

284290

@@ -374,9 +380,15 @@ def _convert_aggregation_temporality(
374380
if current_point.aggregation_temporality is aggregation_temporality:
375381
return current_point
376382

383+
max_ = current_point.max
384+
min_ = current_point.min
385+
377386
if aggregation_temporality is AggregationTemporality.CUMULATIVE:
378387
start_time_unix_nano = previous_point.start_time_unix_nano
379388
sum_ = current_point.sum + previous_point.sum
389+
# Only update min/max on delta -> cumulative
390+
max_ = max(current_point.max, previous_point.max)
391+
min_ = min(current_point.min, previous_point.min)
380392
bucket_counts = [
381393
curr_count + prev_count
382394
for curr_count, prev_count in zip(
@@ -394,12 +406,14 @@ def _convert_aggregation_temporality(
394406
]
395407

396408
return HistogramPoint(
397-
start_time_unix_nano=start_time_unix_nano,
398-
time_unix_nano=current_point.time_unix_nano,
409+
aggregation_temporality=aggregation_temporality,
399410
bucket_counts=bucket_counts,
400411
explicit_bounds=current_point.explicit_bounds,
412+
max=max_,
413+
min=min_,
414+
start_time_unix_nano=start_time_unix_nano,
401415
sum=sum_,
402-
aggregation_temporality=aggregation_temporality,
416+
time_unix_nano=current_point.time_unix_nano,
403417
)
404418
return None
405419

opentelemetry-sdk/src/opentelemetry/sdk/_metrics/point.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ class AggregationTemporality(IntEnum):
3030

3131
@dataclass(frozen=True)
3232
class Sum:
33+
aggregation_temporality: AggregationTemporality
34+
is_monotonic: bool
3335
start_time_unix_nano: int
3436
time_unix_nano: int
3537
value: Union[int, float]
36-
aggregation_temporality: AggregationTemporality
37-
is_monotonic: bool
3838

3939

4040
@dataclass(frozen=True)
@@ -45,12 +45,14 @@ class Gauge:
4545

4646
@dataclass(frozen=True)
4747
class Histogram:
48-
start_time_unix_nano: int
49-
time_unix_nano: int
48+
aggregation_temporality: AggregationTemporality
5049
bucket_counts: Sequence[int]
5150
explicit_bounds: Sequence[float]
51+
max: int
52+
min: int
53+
start_time_unix_nano: int
5254
sum: Union[int, float]
53-
aggregation_temporality: AggregationTemporality
55+
time_unix_nano: int
5456

5557

5658
PointT = Union[Sum, Gauge, Histogram]

opentelemetry-sdk/tests/metrics/test_aggregation.py

Lines changed: 65 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -624,12 +624,14 @@ class TestHistogramConvertAggregationTemporality(TestCase):
624624
def test_previous_point_none(self):
625625

626626
current_point = HistogramPoint(
627-
start_time_unix_nano=0,
628-
time_unix_nano=1,
627+
aggregation_temporality=AggregationTemporality.DELTA,
629628
bucket_counts=[0, 2, 1, 2, 0],
630629
explicit_bounds=[0, 5, 10, 25],
630+
max=24,
631+
min=2,
632+
start_time_unix_nano=0,
631633
sum=70,
632-
aggregation_temporality=AggregationTemporality.DELTA,
634+
time_unix_nano=1,
633635
)
634636

635637
self.assertEqual(
@@ -648,42 +650,50 @@ def test_previous_point_non_cumulative(self):
648650

649651
_convert_aggregation_temporality(
650652
HistogramPoint(
651-
start_time_unix_nano=0,
652-
time_unix_nano=1,
653+
aggregation_temporality=AggregationTemporality.DELTA,
653654
bucket_counts=[0, 2, 1, 2, 0],
654655
explicit_bounds=[0, 5, 10, 25],
656+
max=24,
657+
min=2,
658+
start_time_unix_nano=0,
655659
sum=70,
656-
aggregation_temporality=AggregationTemporality.DELTA,
660+
time_unix_nano=1,
657661
),
658662
HistogramPoint(
659-
start_time_unix_nano=1,
660-
time_unix_nano=2,
663+
aggregation_temporality=AggregationTemporality.DELTA,
661664
bucket_counts=[0, 1, 3, 0, 0],
662665
explicit_bounds=[0, 5, 10, 25],
666+
max=9,
667+
min=2,
668+
start_time_unix_nano=1,
663669
sum=35,
664-
aggregation_temporality=AggregationTemporality.DELTA,
670+
time_unix_nano=2,
665671
),
666672
AggregationTemporality.DELTA,
667673
),
668674

669675
def test_same_aggregation_temporality_cumulative(self):
670676
current_point = HistogramPoint(
671-
start_time_unix_nano=0,
672-
time_unix_nano=2,
677+
aggregation_temporality=AggregationTemporality.CUMULATIVE,
673678
bucket_counts=[0, 3, 4, 2, 0],
674679
explicit_bounds=[0, 5, 10, 25],
680+
max=24,
681+
min=1,
682+
start_time_unix_nano=0,
675683
sum=105,
676-
aggregation_temporality=AggregationTemporality.CUMULATIVE,
684+
time_unix_nano=2,
677685
)
678686
self.assertEqual(
679687
_convert_aggregation_temporality(
680688
HistogramPoint(
681-
start_time_unix_nano=0,
682-
time_unix_nano=1,
689+
aggregation_temporality=AggregationTemporality.CUMULATIVE,
683690
bucket_counts=[0, 2, 1, 2, 0],
684691
explicit_bounds=[0, 5, 10, 25],
692+
max=24,
693+
min=1,
694+
start_time_unix_nano=0,
685695
sum=70,
686-
aggregation_temporality=AggregationTemporality.CUMULATIVE,
696+
time_unix_nano=1,
687697
),
688698
current_point,
689699
AggregationTemporality.CUMULATIVE,
@@ -693,23 +703,27 @@ def test_same_aggregation_temporality_cumulative(self):
693703

694704
def test_same_aggregation_temporality_delta(self):
695705
current_point = HistogramPoint(
696-
start_time_unix_nano=1,
697-
time_unix_nano=2,
706+
aggregation_temporality=AggregationTemporality.DELTA,
698707
bucket_counts=[0, 1, 3, 0, 0],
699708
explicit_bounds=[0, 5, 10, 25],
709+
max=9,
710+
min=1,
711+
start_time_unix_nano=1,
700712
sum=35,
701-
aggregation_temporality=AggregationTemporality.DELTA,
713+
time_unix_nano=2,
702714
)
703715

704716
self.assertEqual(
705717
_convert_aggregation_temporality(
706718
HistogramPoint(
707-
start_time_unix_nano=0,
708-
time_unix_nano=2,
719+
aggregation_temporality=AggregationTemporality.CUMULATIVE,
709720
bucket_counts=[0, 3, 4, 2, 0],
710721
explicit_bounds=[0, 5, 10, 25],
722+
max=24,
723+
min=1,
724+
start_time_unix_nano=0,
711725
sum=105,
712-
aggregation_temporality=AggregationTemporality.CUMULATIVE,
726+
time_unix_nano=2,
713727
),
714728
current_point,
715729
AggregationTemporality.DELTA,
@@ -719,67 +733,79 @@ def test_same_aggregation_temporality_delta(self):
719733

720734
def test_aggregation_temporality_to_cumulative(self):
721735
current_point = HistogramPoint(
722-
start_time_unix_nano=1,
723-
time_unix_nano=2,
736+
aggregation_temporality=AggregationTemporality.DELTA,
724737
bucket_counts=[0, 1, 3, 0, 0],
725738
explicit_bounds=[0, 5, 10, 25],
739+
max=24,
740+
min=1,
741+
start_time_unix_nano=1,
726742
sum=35,
727-
aggregation_temporality=AggregationTemporality.DELTA,
743+
time_unix_nano=2,
728744
)
729745

730746
self.assertEqual(
731747
_convert_aggregation_temporality(
732748
HistogramPoint(
733-
start_time_unix_nano=0,
734-
time_unix_nano=1,
749+
aggregation_temporality=AggregationTemporality.CUMULATIVE,
735750
bucket_counts=[0, 2, 1, 2, 0],
736751
explicit_bounds=[0, 5, 10, 25],
752+
max=24,
753+
min=1,
754+
start_time_unix_nano=0,
737755
sum=70,
738-
aggregation_temporality=AggregationTemporality.CUMULATIVE,
756+
time_unix_nano=1,
739757
),
740758
current_point,
741759
AggregationTemporality.CUMULATIVE,
742760
),
743761
HistogramPoint(
744-
start_time_unix_nano=0,
745-
time_unix_nano=2,
762+
aggregation_temporality=AggregationTemporality.CUMULATIVE,
746763
bucket_counts=[0, 3, 4, 2, 0],
747764
explicit_bounds=[0, 5, 10, 25],
765+
max=24,
766+
min=1,
767+
start_time_unix_nano=0,
748768
sum=105,
749-
aggregation_temporality=AggregationTemporality.CUMULATIVE,
769+
time_unix_nano=2,
750770
),
751771
)
752772

753773
def test_aggregation_temporality_to_delta(self):
754774
current_point = HistogramPoint(
755-
start_time_unix_nano=0,
756-
time_unix_nano=2,
775+
aggregation_temporality=AggregationTemporality.CUMULATIVE,
757776
bucket_counts=[0, 3, 4, 2, 0],
758777
explicit_bounds=[0, 5, 10, 25],
778+
max=22,
779+
min=3,
780+
start_time_unix_nano=0,
759781
sum=105,
760-
aggregation_temporality=AggregationTemporality.CUMULATIVE,
782+
time_unix_nano=2,
761783
)
762784

763785
self.assertEqual(
764786
_convert_aggregation_temporality(
765787
HistogramPoint(
766-
start_time_unix_nano=0,
767-
time_unix_nano=1,
788+
aggregation_temporality=AggregationTemporality.CUMULATIVE,
768789
bucket_counts=[0, 2, 1, 2, 0],
769790
explicit_bounds=[0, 5, 10, 25],
791+
max=24,
792+
min=1,
793+
start_time_unix_nano=0,
770794
sum=70,
771-
aggregation_temporality=AggregationTemporality.CUMULATIVE,
795+
time_unix_nano=1,
772796
),
773797
current_point,
774798
AggregationTemporality.DELTA,
775799
),
776800
HistogramPoint(
777-
start_time_unix_nano=1,
778-
time_unix_nano=2,
801+
aggregation_temporality=AggregationTemporality.DELTA,
779802
bucket_counts=[0, 1, 3, 0, 0],
780803
explicit_bounds=[0, 5, 10, 25],
804+
max=22,
805+
min=3,
806+
start_time_unix_nano=1,
781807
sum=35,
782-
aggregation_temporality=AggregationTemporality.DELTA,
808+
time_unix_nano=2,
783809
),
784810
)
785811

opentelemetry-sdk/tests/metrics/test_point.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ class TestDatapointToJSON(TestCase):
3737
def test_sum(self):
3838
point = _create_metric(
3939
Sum(
40+
aggregation_temporality=2,
41+
is_monotonic=True,
4042
start_time_unix_nano=10,
4143
time_unix_nano=20,
4244
value=9,
43-
aggregation_temporality=2,
44-
is_monotonic=True,
4545
)
4646
)
4747
self.assertEqual(
48-
'{"attributes": {"attr-key": "test-val"}, "description": "test-description", "instrumentation_info": "InstrumentationInfo(name, version, None)", "name": "test-name", "resource": "BoundedAttributes({\'resource-key\': \'resource-val\'}, maxlen=None)", "unit": "test-unit", "point": {"start_time_unix_nano": 10, "time_unix_nano": 20, "value": 9, "aggregation_temporality": 2, "is_monotonic": true}}',
48+
'{"attributes": {"attr-key": "test-val"}, "description": "test-description", "instrumentation_info": "InstrumentationInfo(name, version, None)", "name": "test-name", "resource": "BoundedAttributes({\'resource-key\': \'resource-val\'}, maxlen=None)", "unit": "test-unit", "point": {"aggregation_temporality": 2, "is_monotonic": true, "start_time_unix_nano": 10, "time_unix_nano": 20, "value": 9}}',
4949
point.to_json(),
5050
)
5151

@@ -59,16 +59,18 @@ def test_gauge(self):
5959
def test_histogram(self):
6060
point = _create_metric(
6161
Histogram(
62-
start_time_unix_nano=50,
63-
time_unix_nano=60,
62+
aggregation_temporality=1,
6463
bucket_counts=[0, 0, 1, 0],
6564
explicit_bounds=[0.1, 0.5, 0.9, 1],
66-
aggregation_temporality=1,
65+
max=0.8,
66+
min=0.8,
67+
start_time_unix_nano=50,
6768
sum=0.8,
69+
time_unix_nano=60,
6870
)
6971
)
7072
self.maxDiff = None
7173
self.assertEqual(
72-
'{"attributes": {"attr-key": "test-val"}, "description": "test-description", "instrumentation_info": "InstrumentationInfo(name, version, None)", "name": "test-name", "resource": "BoundedAttributes({\'resource-key\': \'resource-val\'}, maxlen=None)", "unit": "test-unit", "point": {"start_time_unix_nano": 50, "time_unix_nano": 60, "bucket_counts": [0, 0, 1, 0], "explicit_bounds": [0.1, 0.5, 0.9, 1], "sum": 0.8, "aggregation_temporality": 1}}',
74+
'{"attributes": {"attr-key": "test-val"}, "description": "test-description", "instrumentation_info": "InstrumentationInfo(name, version, None)", "name": "test-name", "resource": "BoundedAttributes({\'resource-key\': \'resource-val\'}, maxlen=None)", "unit": "test-unit", "point": {"aggregation_temporality": 1, "bucket_counts": [0, 0, 1, 0], "explicit_bounds": [0.1, 0.5, 0.9, 1], "max": 0.8, "min": 0.8, "start_time_unix_nano": 50, "sum": 0.8, "time_unix_nano": 60}}',
7375
point.to_json(),
7476
)

0 commit comments

Comments
 (0)