Skip to content

Commit d2de661

Browse files
pichlermarcdyladanFlarna
authored
feat(sdk-metrics-base): implement min/max recording for Histograms (#3032)
* feat(sdk-metrics-base): prepare min/max collection. * chore: updating submodule for otlp-grpc-exporter-base * chore: updating submodule for otlp-proto-exporter-base * feat(sdk-trace-base): implement min/max recording, add tests. * feat(docs): update metrics exporter compatibility. * fix(changelog): add changelog entry. * fix(changelog): add more detail to changelog. * fix(changelog): reword, appease linter. * refactor(sdk-metrics-base): inline hasMinMax(), reformat. * fix(otlp-transformer): simplify distinction with for data with min/max and without. Co-authored-by: Daniel Dyla <[email protected]> Co-authored-by: Gerhard Stöbich <[email protected]>
1 parent fa295a3 commit d2de661

File tree

19 files changed

+323
-148
lines changed

19 files changed

+323
-148
lines changed

examples/otlp-exporter-node/docker/docker-compose.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ version: "3"
22
services:
33
# Collector
44
collector:
5-
image: otel/opentelemetry-collector-contrib:0.50.0
5+
image: otel/opentelemetry-collector-contrib:0.53.0
66
# image: otel/opentelemetry-collector-contrib:latest
77
command: ["--config=/conf/collector-config.yaml"]
88
volumes:

experimental/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ All notable changes to experimental packages in this project will be documented
77
### :boom: Breaking Change
88

99
* fix: remove aws and gcp detector from SDK #3024 @flarna
10+
* feat(sdk-metrics-base): implement min/max recording for Histograms #3032 @pichlermarc
11+
* adds `min`/`max` recording to Histograms
12+
* updates [opentelemetry-proto](https://github.com/open-telemetry/opentelemetry-proto) to `0.18` so that `min` and
13+
`max` can be exported. This change breaks the OTLP/JSON Metric Exporter for all collector versions `<0.52` due to
14+
[open-telemetry/opentelemetry-collector#5312](https://github.com/open-telemetry/opentelemetry-collector/issues/5312).
1015

1116
### :rocket: (Enhancement)
1217

experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![Apache License][license-image]][license-image]
55

66
This module provides exporter for web and node to be used with [opentelemetry-collector][opentelemetry-collector-url].
7-
Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.16 <=0.50`.
7+
Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.16 <=0.53`.
88

99
## Installation
1010

experimental/packages/opentelemetry-exporter-metrics-otlp-grpc/test/metricsHelper.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,12 @@ export function ensureExportedHistogramIsCorrect(
196196
exemplars: [],
197197
flags: 0,
198198
_sum: 'sum',
199+
_min: 'min',
200+
_max: 'max',
199201
sum: 21,
200202
count: '2',
203+
min: 7,
204+
max: 14,
201205
startTimeUnixNano: String(startTime),
202206
timeUnixNano: String(time),
203207
bucketCounts,

experimental/packages/opentelemetry-exporter-metrics-otlp-http/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![Apache License][license-image]][license-image]
55

66
This module provides exporter for web and node to be used with [opentelemetry-collector][opentelemetry-collector-url].
7-
Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.48 <=0.50`.
7+
Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.52 <=0.53`.
88

99
## Installation
1010

experimental/packages/opentelemetry-exporter-metrics-otlp-http/test/metricsHelper.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ export function ensureHistogramIsCorrect(
370370
attributes: [],
371371
sum: 21,
372372
count: 2,
373+
min: 7,
374+
max: 14,
373375
startTimeUnixNano: startTime,
374376
timeUnixNano: time,
375377
bucketCounts,

experimental/packages/opentelemetry-exporter-metrics-otlp-proto/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![Apache License][license-image]][license-image]
55

66
This module provides exporter for node to be used with [opentelemetry-collector][opentelemetry-collector-url].
7-
Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.32 <=0.50`.
7+
Compatible with [opentelemetry-collector][opentelemetry-collector-url] versions `>=0.32 <=0.53`.
88

99
## Installation
1010

experimental/packages/opentelemetry-exporter-metrics-otlp-proto/test/metricsHelper.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ export function ensureExportedHistogramIsCorrect(
187187
{
188188
sum: 21,
189189
count: '2',
190+
min: 7,
191+
max: 14,
190192
startTimeUnixNano: String(startTime),
191193
timeUnixNano: String(time),
192194
bucketCounts,

experimental/packages/opentelemetry-sdk-metrics-base/src/aggregator/Histogram.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,29 @@ function createNewEmptyCheckpoint(boundaries: number[]): Histogram {
3737
},
3838
sum: 0,
3939
count: 0,
40+
hasMinMax: false,
41+
min: Infinity,
42+
max: -1
4043
};
4144
}
4245

4346
export class HistogramAccumulation implements Accumulation {
4447
constructor(
4548
private readonly _boundaries: number[],
49+
private _recordMinMax = true,
4650
private _current: Histogram = createNewEmptyCheckpoint(_boundaries)
4751
) {}
4852

4953
record(value: number): void {
5054
this._current.count += 1;
5155
this._current.sum += value;
5256

57+
if (this._recordMinMax) {
58+
this._current.min = Math.min(value, this._current.min);
59+
this._current.max = Math.max(value, this._current.max);
60+
this._current.hasMinMax = true;
61+
}
62+
5363
for (let i = 0; i < this._boundaries.length; i++) {
5464
if (value < this._boundaries[i]) {
5565
this._current.buckets.counts[i] += 1;
@@ -74,11 +84,12 @@ export class HistogramAggregator implements Aggregator<HistogramAccumulation> {
7484

7585
/**
7686
* @param _boundaries upper bounds of recorded values.
87+
* @param _recordMinMax If set to true, min and max will be recorded. Otherwise, min and max will not be recorded.
7788
*/
78-
constructor(private readonly _boundaries: number[]) {}
89+
constructor(private readonly _boundaries: number[], private readonly _recordMinMax: boolean) {}
7990

8091
createAccumulation() {
81-
return new HistogramAccumulation(this._boundaries);
92+
return new HistogramAccumulation(this._boundaries, this._recordMinMax);
8293
}
8394

8495
/**
@@ -98,13 +109,32 @@ export class HistogramAggregator implements Aggregator<HistogramAccumulation> {
98109
mergedCounts[idx] = previousCounts[idx] + deltaCounts[idx];
99110
}
100111

101-
return new HistogramAccumulation(previousValue.buckets.boundaries, {
112+
let min = Infinity;
113+
let max = -1;
114+
115+
if (this._recordMinMax) {
116+
if (previousValue.hasMinMax && deltaValue.hasMinMax) {
117+
min = Math.min(previousValue.min, deltaValue.min);
118+
max = Math.max(previousValue.max, deltaValue.max);
119+
} else if (previousValue.hasMinMax) {
120+
min = previousValue.min;
121+
max = previousValue.max;
122+
} else if (deltaValue.hasMinMax) {
123+
min = deltaValue.min;
124+
max = deltaValue.max;
125+
}
126+
}
127+
128+
return new HistogramAccumulation(previousValue.buckets.boundaries, this._recordMinMax, {
102129
buckets: {
103130
boundaries: previousValue.buckets.boundaries,
104131
counts: mergedCounts,
105132
},
106133
count: previousValue.count + deltaValue.count,
107134
sum: previousValue.sum + deltaValue.sum,
135+
hasMinMax: this._recordMinMax && (previousValue.hasMinMax || deltaValue.hasMinMax),
136+
min: min,
137+
max: max
108138
});
109139
}
110140

@@ -123,13 +153,16 @@ export class HistogramAggregator implements Aggregator<HistogramAccumulation> {
123153
diffedCounts[idx] = currentCounts[idx] - previousCounts[idx];
124154
}
125155

126-
return new HistogramAccumulation(previousValue.buckets.boundaries, {
156+
return new HistogramAccumulation(previousValue.buckets.boundaries, this._recordMinMax, {
127157
buckets: {
128158
boundaries: previousValue.buckets.boundaries,
129159
counts: diffedCounts,
130160
},
131161
count: currentValue.count - previousValue.count,
132162
sum: currentValue.sum - previousValue.sum,
163+
hasMinMax: false,
164+
min: Infinity,
165+
max: -1
133166
});
134167
}
135168

experimental/packages/opentelemetry-sdk-metrics-base/src/aggregator/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ export interface Histogram {
5959
};
6060
sum: number;
6161
count: number;
62+
hasMinMax: boolean;
63+
min: number;
64+
max: number;
6265
}
6366

6467
/**

0 commit comments

Comments
 (0)