-
Notifications
You must be signed in to change notification settings - Fork 821
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(aggregators): implement histogram aggregator #927 #930
feat(aggregators): implement histogram aggregator #927 #930
Conversation
a8f3010
to
55a57e8
Compare
Codecov Report
@@ Coverage Diff @@
## master #930 +/- ##
==========================================
+ Coverage 94.95% 95.02% +0.06%
==========================================
Files 204 209 +5
Lines 8409 8541 +132
Branches 763 766 +3
==========================================
+ Hits 7985 8116 +131
- Misses 424 425 +1
|
55a57e8
to
3b35c60
Compare
packages/opentelemetry-metrics/src/export/aggregators/histogram.ts
Outdated
Show resolved
Hide resolved
return this._lastCheckpoint.count; | ||
} | ||
|
||
get checkpoint() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK only toPoint
method is used by exporter to export the data, why do we need to expose sum
, count
and checkpoint
? I think we should expose as minimal as possible to avoid breaking changes later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As same as above, i've tried to match the go implementation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edit: From the spec here, we should expose a toCheckpoint
rather than toPoint
, so thats why i've added this one. However i think we need to rename it in other aggregators, so i'll use toPoint
too and we'll make a PR to rename them later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if it is called toPoint
in other aggregators, we should use the same here. If it needs to be renamed, it should be renamed everywhere (including here) in a separate PR. Don't want to be in a state where we have both correct and incorrect naming in the same package.
this._currentCheckpoint.buckets.counts[this._boundaries.length] += 1; | ||
} | ||
|
||
resetCheckpoint(): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just reset()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just curious to know, who is responsible for calling this method? Does it end user or exporter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree it make more sense. On the call side, the spec clearly define that here, i believe what they call a Integrator
is our current Batcher
packages/opentelemetry-metrics/src/export/aggregators/histogram.ts
Outdated
Show resolved
Hide resolved
packages/opentelemetry-metrics/src/export/aggregators/histogram.ts
Outdated
Show resolved
Hide resolved
packages/opentelemetry-metrics/src/export/aggregators/histogram.ts
Outdated
Show resolved
Hide resolved
it('should update the second bucket', () => { | ||
const aggregator = new HistogramAggregator([100, 200]); | ||
aggregator.update(150); | ||
aggregator.reset(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like reset
call is always required to get last updated point, (curious to know) who is responsible for calling this reset
on HistogramAggregator
? With other aggregators, toPoint()
will always gives you current point without making a call to reset
. Maybe I am missing something here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've answered here: #930 (comment)
bc63cab
to
1b76765
Compare
e2eaca3
to
dde41d9
Compare
Tests failures are related to gts like others PR, i believe we can ignore since it should be fixed when #958 will be merged |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, one issue with naming
@@ -37,6 +37,15 @@ export interface Distribution { | |||
sum: number; | |||
} | |||
|
|||
export interface Histogram { | |||
buckets: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is it plural if it is an object, could this be a bucket
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is describing all of the buckets. For instance if you have three buckets (<10
, <20
, <30
) with measurements of [5, 5, 5, 5, 5, 15, 15, 15, 25]
, you would have:
hist: Histogram = {
buckets: {
boundaries: [10, 20, 30],
counts: [5, 3, 1],
},
sum: 95,
count: 9
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vmarchaud maybe you can add comments on the interface explaining that the boundaries are upper boundaries, the counts are the number of measurements in the bucket, and so on. I think this will not be clear to people who need to maintain this later if you are not here to walk them through it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm shouldn't we have then
hist: Histogram = {
buckets: [
{
boundary: 10,
count: 5,
},
{
boundary: 20,
count: 3,
},
{
boundary: 30,
count: 1,
},
],
sum: 95,
count: 9
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that would be one different way to do it, but I don't think one way is any more correct than another
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that its current form feel non-javascript, it's because i've just ported the same logic from Go to JS. I will try to make it clearer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added the following comment to explain why this structure is needed:
/**
* Buckets are implemented using two different array:
* - boundaries contains every boundary (which are upper boundary for each slice)
* - counts contains count of event for each slice
*
* Note that we'll always have n+1 (where n is the number of boundaries) slice
* because we need to count event that are above the highest boundary. This is the
* reason why it's not implement using array of object, because the last slice
* dont have any boundary.
*
* Example if we measure the values: [5, 30, 5, 40, 5, 15, 15, 15, 25]
* with the boundaries [ 10, 20, 30 ], we will have the following state:
*
* buckets: {
* boundaries: [10, 20, 30],
* counts: [3, 3, 2, 1],
* }
*/
076a343
to
fc70e3a
Compare
fc70e3a
to
fa3e420
Compare
…astify version.ts (open-telemetry#930) Co-authored-by: Gerhard Stöbich <[email protected]>
…astify version.ts (open-telemetry#930) Co-authored-by: Gerhard Stöbich <[email protected]>
…astify version.ts (open-telemetry#930) Co-authored-by: Gerhard Stöbich <[email protected]>
Ported the Go implementation to TS and moved each aggregator to its own file to avoid having one massive file containing all implementations