-
Notifications
You must be signed in to change notification settings - Fork 438
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
Add Counter and Histogram Aggregators #178
Add Counter and Histogram Aggregators #178
Conversation
|
||
#include <variant> | ||
#include <vector> | ||
#include <mutex> |
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.
nit - is there a reason these are not alphabetically sorted? If not, I would suggest to sort them.
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.
the format tools seem to reorder these
Aggregator() = default; | ||
|
||
/** | ||
* Recieves a captured value from the instrument and applies it to the current aggregator value. |
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.
* Recieves a captured value from the instrument and applies it to the current aggregator value. | |
* Receives a captured value from the instrument and applies it to the current aggregator value. |
void update(T val) override | ||
{ | ||
this->mu_.lock(); | ||
this->values_[0] += val; // atomic operation |
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.
For int and long, is it possible to spin + CAS (compare and swap) to achieve better perf?
Not blocking this PR though.
if (this->kind_ == other.kind_) | ||
{ | ||
this->mu_.lock(); | ||
this->values_[0] += other.values_[0]; // atomic operation afaik |
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.
curious, what does // atomic operation afaik
mean?
sdk/include/opentelemetry/sdk/metrics/aggregator/histogram_aggregator.h
Outdated
Show resolved
Hide resolved
HistogramAggregator(metrics_api::BoundInstrumentKind kind, std::vector<double> boundaries) | ||
{ | ||
this->kind_ = kind; | ||
boundaries_ = boundaries; |
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.
Do we want to validate if the boundaries is monotonic?
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.
Added a check which throws an invalid_argument exception if provided boundaries are not sorted
} | ||
} | ||
|
||
// Alternate implementation with binary search |
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'll be helpful to put a comment on the design decision - e.g. why would we choose linear search vs. binary search.
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.
Included some background on the topic above the update function -- let me know if this is not enough and I'll gladly add a more thorough explanation.
|
||
for (int i = 0; i < bucketCounts_.size(); i++) | ||
{ | ||
bucketCounts_[i] += other.bucketCounts_[i]; |
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.
Who should be responsible of making sure the other.bucketCounts
won't overflow? Do we in general want to check the buckets are the same before proceeding?
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.
This is a good suggestion. When you say " other.bucketCounts
won't overflow," are you referring to a scenario in which adding the values together would exceed the capacity of the data type?
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.
For example, if other.bucketCounts_.size() <= i
.
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.
There are two separate things:
- index overflow while accessing the bucketCounts_.
- value overflow while performing
+=
.
1 is more scary.
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 preempted the possibility of an index out of bounds issue by ensuring that the boundary vectors of both aggregators are identical.
For the value overflow, I can think of some hacky ways to do it, for example if abs(a)+abs(b) < 0 to indicate a wraparound. I could also subtract from a variable set to int_max. I feel like there has to be a native c++ tool/function which does this but I can't seem to find it...
|
||
/** | ||
* Merges the values of two aggregators in a semantically accurate manner. | ||
* A histogram aggregator can only be merged with another histogram aggregatos with the same boudnaries. |
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.
Theoretically we could merge a more accurate histogram into a less accurate one (e.g. merge [0, 1, 10, 100, 1000) into [0, 10, 1000). Probably not something we should cover 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.
Please find my comments.
6182512
to
c75b549
Compare
Codecov Report
@@ Coverage Diff @@
## master #178 +/- ##
=======================================
Coverage 93.75% 93.75%
=======================================
Files 104 104
Lines 3249 3249
=======================================
Hits 3046 3046
Misses 203 203 |
Addressed comments and rebased. This has a dependency on PR #161 and should be ready to go once that PR has been merged. |
72e2354
to
adb56e1
Compare
Failing Bazel noexcept test although I was under the impression we were allowed to throw exceptions in SDK components? Unsure why the exporter proto CMake test is failing. |
…regator.h Co-authored-by: Reiley Yang <[email protected]>
sdk/include/opentelemetry/sdk/metrics/aggregator/histogram_aggregator.h
Outdated
Show resolved
Hide resolved
…regator.h Co-authored-by: Reiley Yang <[email protected]>
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.
@ankit-bhargava would you fix the CI/Format issue? |
…regator.h Co-authored-by: Reiley Yang <[email protected]>
…regator.h Co-authored-by: Reiley Yang <[email protected]>
…va/opentelemetry-cpp into metrics-agg-ctrhist
@reyang |
This PR builds out SDK support for the Counter and Histogram Aggregators which combine updates to metric instruments in meaningful values. Each aggregator stores exportable values in a vector format for ease of use further down the metrics data pipeline. All aggregators are derived from a base Aggregator abstract class which holds functions and data relevant to all aggregators. Additional data structures, such as a vector for histogram boundaries, are added on a case by case basis. Aggregators are dependent on the Metric Instruments API (pending approval in PR # 161) and will not compile without those files.
Also included are tests for each aggregator which validate the correctness of aggregation in both single-threaded and concurrent situations.
Note: We templated aggregators to support a wider array of scalar types. This templating prevents us from using out of line declarations as we normally would. As a result, we left all implementation code in the header file. If there are any suggestions to remedy this we will gladly make the change.
This PR is part of a series of PRs to add a full implementation of metrics API and SDK support.