1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
5 #ifdef ENABLE_METRICS_PREVIEW
13 # include "opentelemetry/_metrics/sync_instruments.h"
14 # include "opentelemetry/common/macros.h"
15 # include "opentelemetry/sdk/_metrics/aggregator/counter_aggregator.h"
16 # include "opentelemetry/sdk/_metrics/aggregator/min_max_sum_count_aggregator.h"
17 # include "opentelemetry/sdk/_metrics/instrument.h"
19 OPENTELEMETRY_BEGIN_NAMESPACE
25 # if defined(_MSC_VER)
26 # pragma warning(push)
27 # pragma warning(disable : 4250) // inheriting methods via dominance
31 class BoundCounter final
: public BoundSynchronousInstrument
<T
>,
32 public opentelemetry::metrics::BoundCounter
<T
>
36 BoundCounter() = default;
38 BoundCounter(nostd::string_view name
,
39 nostd::string_view description
,
40 nostd::string_view unit
,
42 : BoundSynchronousInstrument
<T
>(
47 opentelemetry::metrics::InstrumentKind::Counter
,
48 std::shared_ptr
<Aggregator
<T
>>(new CounterAggregator
<T
>(
49 opentelemetry::metrics::InstrumentKind::Counter
))) // Aggregator is chosen here
53 * Add adds the value to the counter's sum. The labels are already linked to the instrument
54 * and are not specified.
56 * @param value the numerical representation of the metric being captured
57 * @param labels the set of labels, as key-value pairs
59 virtual void add(T value
) override
64 throw std::invalid_argument("Counter instrument updates must be non-negative.");
77 class Counter final
: public SynchronousInstrument
<T
>, public opentelemetry::metrics::Counter
<T
>
83 Counter(nostd::string_view name
,
84 nostd::string_view description
,
85 nostd::string_view unit
,
87 : SynchronousInstrument
<T
>(name
,
91 opentelemetry::metrics::InstrumentKind::Counter
)
95 * Bind creates a bound instrument for this counter. The labels are
96 * associated with values recorded via subsequent calls to Record.
98 * @param labels the set of labels, as key-value pairs.
99 * @return a BoundCounter tied to the specified labels
102 virtual nostd::shared_ptr
<opentelemetry::metrics::BoundCounter
<T
>> bindCounter(
103 const opentelemetry::common::KeyValueIterable
&labels
) override
106 std::string labelset
= KvToString(labels
);
107 if (boundInstruments_
.find(labelset
) == boundInstruments_
.end())
109 auto sp1
= nostd::shared_ptr
<opentelemetry::metrics::BoundCounter
<T
>>(
110 new BoundCounter
<T
>(this->name_
, this->description_
, this->unit_
, this->enabled_
));
111 boundInstruments_
[labelset
] = sp1
;
117 boundInstruments_
[labelset
]->inc_ref();
118 auto ret
= boundInstruments_
[labelset
];
125 * Add adds the value to the counter's sum. The labels should contain
126 * the keys and values to be associated with this value. Counters only
127 * accept positive valued updates.
129 * @param value the numerical representation of the metric being captured
130 * @param labels the set of labels, as key-value pairs
132 virtual void add(T value
, const opentelemetry::common::KeyValueIterable
&labels
) override
137 throw std::invalid_argument("Counter instrument updates must be non-negative.");
144 auto sp
= bindCounter(labels
);
150 virtual std::vector
<Record
> GetRecords() override
153 std::vector
<Record
> ret
;
154 std::vector
<std::string
> toDelete
;
155 for (const auto &x
: boundInstruments_
)
157 if (x
.second
->get_ref() == 0)
159 toDelete
.push_back(x
.first
);
161 # ifdef OPENTELEMETRY_RTTI_ENABLED
162 auto agg_ptr
= dynamic_cast<BoundCounter
<T
> *>(x
.second
.get())->GetAggregator();
164 auto agg_ptr
= static_cast<BoundCounter
<T
> *>(x
.second
.get())->GetAggregator();
166 if (agg_ptr
->is_updated())
168 agg_ptr
->checkpoint();
169 ret
.push_back(Record(x
.second
->GetName(), x
.second
->GetDescription(), x
.first
, agg_ptr
));
172 for (const auto &x
: toDelete
)
174 boundInstruments_
.erase(x
);
180 virtual void update(T val
, const opentelemetry::common::KeyValueIterable
&labels
) override
185 // A collection of the bound instruments created by this unbound instrument identified by their
187 std::unordered_map
<std::string
, nostd::shared_ptr
<opentelemetry::metrics::BoundCounter
<T
>>>
192 class BoundUpDownCounter final
: public BoundSynchronousInstrument
<T
>,
193 virtual public opentelemetry::metrics::BoundUpDownCounter
<T
>
197 BoundUpDownCounter() = default;
199 BoundUpDownCounter(nostd::string_view name
,
200 nostd::string_view description
,
201 nostd::string_view unit
,
203 : BoundSynchronousInstrument
<T
>(name
,
207 opentelemetry::metrics::InstrumentKind::UpDownCounter
,
208 std::shared_ptr
<Aggregator
<T
>>(new CounterAggregator
<T
>(
209 opentelemetry::metrics::InstrumentKind::UpDownCounter
)))
213 * Add adds the value to the counter's sum. The labels are already linked to the instrument
214 * and are not specified.
216 * @param value the numerical representation of the metric being captured
217 * @param labels the set of labels, as key-value pairs
219 virtual void add(T value
) override
{ this->update(value
); }
223 class UpDownCounter final
: public SynchronousInstrument
<T
>,
224 public opentelemetry::metrics::UpDownCounter
<T
>
228 UpDownCounter() = default;
230 UpDownCounter(nostd::string_view name
,
231 nostd::string_view description
,
232 nostd::string_view unit
,
234 : SynchronousInstrument
<T
>(name
,
238 opentelemetry::metrics::InstrumentKind::UpDownCounter
)
242 * Bind creates a bound instrument for this counter. The labels are
243 * associated with values recorded via subsequent calls to Record.
245 * @param labels the set of labels, as key-value pairs.
246 * @return a BoundIntCounter tied to the specified labels
248 nostd::shared_ptr
<opentelemetry::metrics::BoundUpDownCounter
<T
>> bindUpDownCounter(
249 const opentelemetry::common::KeyValueIterable
&labels
) override
252 std::string labelset
= KvToString(labels
);
253 if (boundInstruments_
.find(labelset
) == boundInstruments_
.end())
255 auto sp1
= nostd::shared_ptr
<opentelemetry::metrics::BoundUpDownCounter
<T
>>(
256 new BoundUpDownCounter
<T
>(this->name_
, this->description_
, this->unit_
, this->enabled_
));
257 boundInstruments_
[labelset
] = sp1
;
263 boundInstruments_
[labelset
]->inc_ref();
264 auto ret
= boundInstruments_
[labelset
];
271 * Add adds the value to the counter's sum. The labels should contain
272 * the keys and values to be associated with this value. Counters only
273 * accept positive valued updates.
275 * @param value the numerical representation of the metric being captured
276 * @param labels the set of labels, as key-value pairs
278 void add(T value
, const opentelemetry::common::KeyValueIterable
&labels
) override
280 auto sp
= bindUpDownCounter(labels
);
285 virtual std::vector
<Record
> GetRecords() override
288 std::vector
<Record
> ret
;
289 std::vector
<std::string
> toDelete
;
290 for (const auto &x
: boundInstruments_
)
292 if (x
.second
->get_ref() == 0)
294 toDelete
.push_back(x
.first
);
296 # ifdef OPENTELEMETRY_RTTI_ENABLED
297 auto agg_ptr
= dynamic_cast<BoundUpDownCounter
<T
> *>(x
.second
.get())->GetAggregator();
299 auto agg_ptr
= static_cast<BoundUpDownCounter
<T
> *>(x
.second
.get())->GetAggregator();
301 if (agg_ptr
->is_updated())
303 agg_ptr
->checkpoint();
304 ret
.push_back(Record(x
.second
->GetName(), x
.second
->GetDescription(), x
.first
, agg_ptr
));
307 for (const auto &x
: toDelete
)
309 boundInstruments_
.erase(x
);
315 virtual void update(T val
, const opentelemetry::common::KeyValueIterable
&labels
) override
320 std::unordered_map
<std::string
, nostd::shared_ptr
<opentelemetry::metrics::BoundUpDownCounter
<T
>>>
325 class BoundValueRecorder final
: public BoundSynchronousInstrument
<T
>,
326 public opentelemetry::metrics::BoundValueRecorder
<T
>
330 BoundValueRecorder() = default;
332 BoundValueRecorder(nostd::string_view name
,
333 nostd::string_view description
,
334 nostd::string_view unit
,
336 : BoundSynchronousInstrument
<T
>(
341 opentelemetry::metrics::InstrumentKind::ValueRecorder
,
342 std::shared_ptr
<Aggregator
<T
>>(new MinMaxSumCountAggregator
<T
>(
343 opentelemetry::metrics::InstrumentKind::ValueRecorder
)))
347 * Add adds the value to the counter's sum. The labels are already linked to the instrument
348 * and are not specified.
350 * @param value the numerical representation of the metric being captured
351 * @param labels the set of labels, as key-value pairs
353 void record(T value
) { this->update(value
); }
357 class ValueRecorder final
: public SynchronousInstrument
<T
>,
358 public opentelemetry::metrics::ValueRecorder
<T
>
362 ValueRecorder() = default;
364 ValueRecorder(nostd::string_view name
,
365 nostd::string_view description
,
366 nostd::string_view unit
,
368 : SynchronousInstrument
<T
>(name
,
372 opentelemetry::metrics::InstrumentKind::ValueRecorder
)
376 * Bind creates a bound instrument for this counter. The labels are
377 * associated with values recorded via subsequent calls to Record.
379 * @param labels the set of labels, as key-value pairs.
380 * @return a BoundIntCounter tied to the specified labels
382 nostd::shared_ptr
<opentelemetry::metrics::BoundValueRecorder
<T
>> bindValueRecorder(
383 const opentelemetry::common::KeyValueIterable
&labels
) override
386 std::string labelset
= KvToString(labels
);
387 if (boundInstruments_
.find(labelset
) == boundInstruments_
.end())
389 auto sp1
= nostd::shared_ptr
<opentelemetry::metrics::BoundValueRecorder
<T
>>(
390 new BoundValueRecorder
<T
>(this->name_
, this->description_
, this->unit_
, this->enabled_
));
391 boundInstruments_
[labelset
] = sp1
;
397 boundInstruments_
[labelset
]->inc_ref();
398 auto ret
= boundInstruments_
[labelset
];
405 * Add adds the value to the counter's sum. The labels should contain
406 * the keys and values to be associated with this value. Counters only
407 * accept positive valued updates.
409 * @param value the numerical representation of the metric being captured
410 * @param labels the set of labels, as key-value pairs
412 void record(T value
, const opentelemetry::common::KeyValueIterable
&labels
) override
414 auto sp
= bindValueRecorder(labels
);
419 virtual std::vector
<Record
> GetRecords() override
422 std::vector
<Record
> ret
;
423 std::vector
<std::string
> toDelete
;
424 for (const auto &x
: boundInstruments_
)
426 if (x
.second
->get_ref() == 0)
428 toDelete
.push_back(x
.first
);
430 # ifdef OPENTELEMETRY_RTTI_ENABLED
431 auto agg_ptr
= dynamic_cast<BoundValueRecorder
<T
> *>(x
.second
.get())->GetAggregator();
433 auto agg_ptr
= static_cast<BoundValueRecorder
<T
> *>(x
.second
.get())->GetAggregator();
435 if (agg_ptr
->is_updated())
437 agg_ptr
->checkpoint();
438 ret
.push_back(Record(x
.second
->GetName(), x
.second
->GetDescription(), x
.first
, agg_ptr
));
441 for (const auto &x
: toDelete
)
443 boundInstruments_
.erase(x
);
449 virtual void update(T value
, const opentelemetry::common::KeyValueIterable
&labels
) override
451 record(value
, labels
);
454 std::unordered_map
<std::string
, nostd::shared_ptr
<opentelemetry::metrics::BoundValueRecorder
<T
>>>
458 # if defined(_MSC_VER)
459 # pragma warning(pop)
462 } // namespace metrics
464 OPENTELEMETRY_END_NAMESPACE