Add Counter and Histogram Aggregators #178
Conversation
|
|
||
| #include <variant> | ||
| #include <vector> | ||
| #include <mutex> |
There was a problem hiding this comment.
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.
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.
| * 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.
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.
curious, what does // atomic operation afaik mean?
| HistogramAggregator(metrics_api::BoundInstrumentKind kind, std::vector<double> boundaries) | ||
| { | ||
| this->kind_ = kind; | ||
| boundaries_ = boundaries; |
There was a problem hiding this comment.
Do we want to validate if the boundaries is monotonic?
There was a problem hiding this comment.
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.
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.
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.
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.
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.
For example, if other.bucketCounts_.size() <= i.
There was a problem hiding this comment.
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.
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.
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.
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 <reyang@microsoft.com>
|
@ankit-bhargava would you fix the CI/Format issue? |
…regator.h Co-authored-by: Reiley Yang <reyang@microsoft.com>
…regator.h Co-authored-by: Reiley Yang <reyang@microsoft.com>
…va/opentelemetry-cpp into metrics-agg-ctrhist
|
@reyang |
…-1.x Update dependency googletest to v1.16.0
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.