]> git.proxmox.com Git - ceph.git/blob - ceph/src/jaegertracing/opentelemetry-cpp/sdk/include/opentelemetry/sdk/_metrics/instrument.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / jaegertracing / opentelemetry-cpp / sdk / include / opentelemetry / sdk / _metrics / instrument.h
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3
4 #pragma once
5 #ifdef ENABLE_METRICS_PREVIEW
6
7 # include <iostream>
8 # include <map>
9 # include <memory>
10 # include <sstream>
11 # include <string>
12 # include <unordered_map>
13 # include <vector>
14 # include "opentelemetry/_metrics/instrument.h"
15 # include "opentelemetry/sdk/_metrics/aggregator/aggregator.h"
16 # include "opentelemetry/sdk/_metrics/record.h"
17 # include "opentelemetry/version.h"
18
19 OPENTELEMETRY_BEGIN_NAMESPACE
20 namespace sdk
21 {
22 namespace metrics
23 {
24
25 # if defined(_MSC_VER)
26 # pragma warning(push)
27 # pragma warning(disable : 4250) // inheriting methods via dominance
28 # endif
29
30 class Instrument : virtual public opentelemetry::metrics::Instrument
31 {
32
33 public:
34 Instrument() = default;
35
36 Instrument(nostd::string_view name,
37 nostd::string_view description,
38 nostd::string_view unit,
39 bool enabled,
40 opentelemetry::metrics::InstrumentKind kind)
41 : name_(name), description_(description), unit_(unit), enabled_(enabled), kind_(kind)
42 {}
43
44 // Returns true if the instrument is enabled and collecting data
45 virtual bool IsEnabled() override { return enabled_; }
46
47 // Return the instrument name
48 virtual nostd::string_view GetName() override { return name_; }
49
50 // Return the instrument description
51 virtual nostd::string_view GetDescription() override { return description_; }
52
53 // Return the insrument's units of measurement
54 virtual nostd::string_view GetUnits() override { return unit_; }
55
56 virtual opentelemetry::metrics::InstrumentKind GetKind() override { return this->kind_; }
57
58 protected:
59 std::string name_;
60 std::string description_;
61 std::string unit_;
62 bool enabled_;
63 std::mutex mu_;
64 opentelemetry::metrics::InstrumentKind kind_;
65 };
66
67 template <class T>
68 class BoundSynchronousInstrument
69 : public Instrument,
70 virtual public opentelemetry::metrics::BoundSynchronousInstrument<T>
71 {
72
73 public:
74 BoundSynchronousInstrument() = default;
75
76 BoundSynchronousInstrument(nostd::string_view name,
77 nostd::string_view description,
78 nostd::string_view unit,
79 bool enabled,
80 opentelemetry::metrics::InstrumentKind kind,
81 std::shared_ptr<Aggregator<T>> agg)
82 : Instrument(name, description, unit, enabled, kind), agg_(agg)
83 {
84 this->inc_ref(); // increase reference count when instantiated
85 }
86
87 /**
88 * Frees the resources associated with this Bound Instrument.
89 * The Metric from which this instrument was created is not impacted.
90 *
91 * @param none
92 * @return void
93 */
94 virtual void unbind() override
95 {
96 this->mu_.lock();
97 ref_ -= 1;
98 this->mu_.unlock();
99 }
100
101 /**
102 * Increments the reference count. This function is used when binding or instantiating.
103 *
104 * @param none
105 * @return void
106 */
107 virtual void inc_ref() override
108 {
109 this->mu_.lock();
110 ref_ += 1;
111 this->mu_.unlock();
112 }
113
114 /**
115 * Returns the current reference count of the instrument. This value is used to
116 * later in the pipeline remove stale instruments.
117 *
118 * @param none
119 * @return current ref count of the instrument
120 */
121 virtual int get_ref() override
122 {
123 this->mu_.lock();
124 auto ret = ref_;
125 this->mu_.unlock();
126 return ret;
127 }
128
129 /**
130 * Records a single synchronous metric event via a call to the aggregator.
131 * Since this is a bound synchronous instrument, labels are not required in
132 * metric capture calls.
133 *
134 * @param value is the numerical representation of the metric being captured
135 * @return void
136 */
137 virtual void update(T value) override
138 {
139 this->mu_.lock();
140 agg_->update(value);
141 this->mu_.unlock();
142 }
143
144 /**
145 * Returns the aggregator responsible for meaningfully combining update values.
146 *
147 * @param none
148 * @return the aggregator assigned to this instrument
149 */
150 virtual std::shared_ptr<Aggregator<T>> GetAggregator() final { return agg_; }
151
152 private:
153 std::shared_ptr<Aggregator<T>> agg_;
154 int ref_ = 0;
155 };
156
157 template <class T>
158 class SynchronousInstrument : public Instrument,
159 virtual public opentelemetry::metrics::SynchronousInstrument<T>
160 {
161
162 public:
163 SynchronousInstrument() = default;
164
165 SynchronousInstrument(nostd::string_view name,
166 nostd::string_view description,
167 nostd::string_view unit,
168 bool enabled,
169 opentelemetry::metrics::InstrumentKind kind)
170 : Instrument(name, description, unit, enabled, kind)
171 {}
172
173 /**
174 * Returns a Bound Instrument associated with the specified labels. Multiples requests
175 * with the same set of labels may return the same Bound Instrument instance.
176 *
177 * It is recommended that callers keep a reference to the Bound Instrument
178 * instead of repeatedly calling this operation.
179 *
180 * @param labels the set of labels, as key-value pairs
181 * @return a Bound Instrument
182 */
183 virtual nostd::shared_ptr<opentelemetry::metrics::BoundSynchronousInstrument<T>> bind(
184 const opentelemetry::common::KeyValueIterable &labels) override
185 {
186 return nostd::shared_ptr<BoundSynchronousInstrument<T>>();
187 }
188
189 // This function is necessary for batch recording and should NOT be called by the user
190 virtual void update(T value, const opentelemetry::common::KeyValueIterable &labels) override = 0;
191
192 /**
193 * Checkpoints instruments and returns a set of records which are ready for processing.
194 * This method should ONLY be called by the Meter Class as part of the export pipeline
195 * as it also prunes bound instruments with no active references.
196 *
197 * @param none
198 * @return vector of Records which hold the data attached to this synchronous instrument
199 */
200 virtual std::vector<Record> GetRecords() = 0;
201 };
202
203 template <class T>
204 class AsynchronousInstrument : public Instrument,
205 virtual public opentelemetry::metrics::AsynchronousInstrument<T>
206 {
207
208 public:
209 AsynchronousInstrument() = default;
210
211 AsynchronousInstrument(nostd::string_view name,
212 nostd::string_view description,
213 nostd::string_view unit,
214 bool enabled,
215 void (*callback)(opentelemetry::metrics::ObserverResult<T>),
216 opentelemetry::metrics::InstrumentKind kind)
217 : Instrument(name, description, unit, enabled, kind)
218 {
219 this->callback_ = callback;
220 }
221
222 /**
223 * Captures data through a manual call rather than the automatic collection process instituted
224 * in the run function. Asynchronous instruments are generally expected to obtain data from
225 * their callbacks rather than direct calls. This function is used by the callback to store data.
226 *
227 * @param value is the numerical representation of the metric being captured
228 * @param labels is the numerical representation of the metric being captured
229 * @return none
230 */
231 virtual void observe(T value, const opentelemetry::common::KeyValueIterable &labels) override = 0;
232
233 virtual std::vector<Record> GetRecords() = 0;
234
235 /**
236 * Captures data by activating the callback function associated with the
237 * instrument and storing its return value. Callbacks for asynchronous
238 * instruments are defined during construction.
239 *
240 * @param none
241 * @return none
242 */
243 virtual void run() override = 0;
244 };
245
246 // Helper functions for turning a common::KeyValueIterable into a string
247 inline void print_value(std::stringstream &ss,
248 opentelemetry::common::AttributeValue &value,
249 bool jsonTypes = false)
250 {
251 switch (value.index())
252 {
253 case opentelemetry::common::AttributeType::kTypeString:
254
255 ss << nostd::get<nostd::string_view>(value);
256
257 break;
258 default:
259 # if __EXCEPTIONS
260 throw std::invalid_argument("Labels must be strings");
261 # else
262 std::terminate();
263 # endif
264 break;
265 }
266 };
267
268 // Utility function which converts maps to strings for better performance
269 inline std::string mapToString(const std::map<std::string, std::string> &conv)
270 {
271 std::stringstream ss;
272 ss << "{";
273 for (auto i : conv)
274 {
275 ss << i.first << ':' << i.second << ',';
276 }
277 ss << "}";
278 return ss.str();
279 }
280
281 inline std::string KvToString(const opentelemetry::common::KeyValueIterable &kv) noexcept
282 {
283 std::stringstream ss;
284 ss << "{";
285 size_t size = kv.size();
286 if (size)
287 {
288 size_t i = 1;
289 kv.ForEachKeyValue(
290 [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept {
291 ss << key << ":";
292 print_value(ss, value, true);
293 if (size != i)
294 {
295 ss << ",";
296 }
297 i++;
298 return true;
299 });
300 };
301 ss << "}";
302 return ss.str();
303 }
304
305 # if defined(_MSC_VER)
306 # pragma warning(pop)
307 # endif
308
309 } // namespace metrics
310 } // namespace sdk
311 OPENTELEMETRY_END_NAMESPACE
312 #endif