1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
5 #ifdef ENABLE_METRICS_PREVIEW
7 # include "opentelemetry/_metrics/instrument.h"
8 # include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
9 # include "opentelemetry/version.h"
16 OPENTELEMETRY_BEGIN_NAMESPACE
22 * This aggregator has two modes. In-order and quantile estimation.
24 * The first mode simply stores all values sent to the Update()
25 * function in a vector and maintains the order they were sent in.
27 * The second mode also stores all values sent to the Update()
28 * function in a vector but sorts this vector when Checkpoint()
29 * is called. This mode also includes a function, Quantile(),
30 * that estimates the quantiles of the recorded data.
32 * @tparam T the type of values stored in this aggregator.
35 class ExactAggregator
: public Aggregator
<T
>
38 ExactAggregator(opentelemetry::metrics::InstrumentKind kind
, bool quant_estimation
= false)
40 static_assert(std::is_arithmetic
<T
>::value
, "Not an arithmetic type");
42 this->checkpoint_
= this->values_
;
43 this->agg_kind_
= AggregatorKind::Exact
;
44 quant_estimation_
= quant_estimation
;
47 ~ExactAggregator() = default;
49 ExactAggregator(const ExactAggregator
&cp
)
51 this->values_
= cp
.values_
;
52 this->checkpoint_
= cp
.checkpoint_
;
53 this->kind_
= cp
.kind_
;
54 this->agg_kind_
= cp
.agg_kind_
;
55 quant_estimation_
= cp
.quant_estimation_
;
56 // use default initialized mutex as they cannot be copied
60 * Receives a captured value from the instrument and adds it to the values_ vector.
62 * @param val, the raw value used in aggregation
64 void update(T val
) override
67 this->updated_
= true;
68 this->values_
.push_back(val
);
73 * Checkpoints the current values. This function will overwrite the current checkpoint with the
74 * current value. Sorts the values_ vector if quant_estimation_ == true
77 void checkpoint() override
80 this->updated_
= false;
81 if (quant_estimation_
)
83 std::sort(this->values_
.begin(), this->values_
.end());
85 this->checkpoint_
= this->values_
;
86 this->values_
.clear();
91 * Merges two exact aggregators' values_ vectors together.
93 * @param other the aggregator to merge with this aggregator
95 void merge(const ExactAggregator
&other
)
97 if (this->kind_
== other
.kind_
)
100 // First merge values
101 this->values_
.insert(this->values_
.end(), other
.values_
.begin(), other
.values_
.end());
102 // Now merge checkpoints
103 this->checkpoint_
.insert(this->checkpoint_
.end(), other
.checkpoint_
.begin(),
104 other
.checkpoint_
.end());
115 * Performs quantile estimation on the checkpoint vector in this aggregator.
116 * This function only works if quant_estimation_ == true.
117 * @param q the quantile to estimate. 0 <= q <= 1
118 * @return the nearest value in the vector to the exact quantile.
120 T
get_quantiles(double q
) override
122 if (!quant_estimation_
)
126 throw std::domain_error("Exact aggregator is not in quantile estimation mode!");
131 if (this->checkpoint_
.size() == 0 || q
< 0 || q
> 1)
135 throw std::invalid_argument("Arg 'q' must be between 0 and 1, inclusive");
140 else if (q
== 0 || this->checkpoint_
.size() == 1)
142 return this->checkpoint_
[0];
146 return this->checkpoint_
[this->checkpoint_
.size() - 1];
150 float position
= float(float(this->checkpoint_
.size() - 1) * q
);
151 int ceiling
= int(ceil(position
));
152 return this->checkpoint_
[ceiling
];
156 //////////////////////////ACCESSOR FUNCTIONS//////////////////////////
157 std::vector
<T
> get_checkpoint() override
{ return this->checkpoint_
; }
159 std::vector
<T
> get_values() override
{ return this->values_
; }
161 bool get_quant_estimation() override
{ return quant_estimation_
; }
164 bool quant_estimation_
; // Used to switch between in-order and quantile estimation modes
166 } // namespace metrics
168 OPENTELEMETRY_END_NAMESPACE