/root/doris/be/src/util/metrics.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | #pragma once |
19 | | |
20 | | #include <rapidjson/document.h> |
21 | | #include <rapidjson/rapidjson.h> |
22 | | #include <stddef.h> |
23 | | #include <stdint.h> |
24 | | |
25 | | #include <atomic> |
26 | | #include <functional> |
27 | | #include <map> |
28 | | #include <memory> |
29 | | #include <mutex> |
30 | | #include <sstream> |
31 | | #include <string> |
32 | | #include <unordered_map> |
33 | | #include <utility> |
34 | | #include <vector> |
35 | | |
36 | | #include "util/core_local.h" |
37 | | #include "util/histogram.h" |
38 | | #include "util/spinlock.h" |
39 | | |
40 | | namespace doris { |
41 | | |
42 | | namespace rj = RAPIDJSON_NAMESPACE; |
43 | | |
44 | | enum class MetricType { COUNTER, GAUGE, HISTOGRAM, SUMMARY, UNTYPED }; |
45 | | |
46 | | enum class MetricUnit { |
47 | | NANOSECONDS, |
48 | | MICROSECONDS, |
49 | | MILLISECONDS, |
50 | | SECONDS, |
51 | | BYTES, |
52 | | ROWS, |
53 | | PERCENT, |
54 | | REQUESTS, |
55 | | OPERATIONS, |
56 | | BLOCKS, |
57 | | ROWSETS, |
58 | | CONNECTIONS, |
59 | | PACKETS, |
60 | | NOUNIT, |
61 | | FILESYSTEM |
62 | | }; |
63 | | |
64 | | std::ostream& operator<<(std::ostream& os, MetricType type); |
65 | | const char* unit_name(MetricUnit unit); |
66 | | |
67 | | using Labels = std::unordered_map<std::string, std::string>; |
68 | | |
69 | | class Metric { |
70 | | public: |
71 | 2.63k | Metric() {} |
72 | 2.61k | virtual ~Metric() {} |
73 | | virtual std::string to_string() const = 0; |
74 | | virtual std::string to_prometheus(const std::string& display_name, const Labels& entity_labels, |
75 | | const Labels& metric_labels) const; |
76 | | virtual rj::Value to_json_value(rj::Document::AllocatorType& allocator) const = 0; |
77 | | |
78 | | private: |
79 | | friend class MetricRegistry; |
80 | | }; |
81 | | |
82 | | // Metric that only can increment |
83 | | template <typename T> |
84 | | class AtomicMetric : public Metric { |
85 | | public: |
86 | 1.69k | AtomicMetric() : _value(T()) {} _ZN5doris12AtomicMetricIlEC2Ev Line | Count | Source | 86 | 1.38k | AtomicMetric() : _value(T()) {} |
_ZN5doris12AtomicMetricImEC2Ev Line | Count | Source | 86 | 308 | AtomicMetric() : _value(T()) {} |
|
87 | 1.68k | virtual ~AtomicMetric() {} _ZN5doris12AtomicMetricIlED2Ev Line | Count | Source | 87 | 1.37k | virtual ~AtomicMetric() {} |
_ZN5doris12AtomicMetricImED2Ev Line | Count | Source | 87 | 308 | virtual ~AtomicMetric() {} |
|
88 | | |
89 | 49 | std::string to_string() const override { return std::to_string(value()); } _ZNK5doris12AtomicMetricIlE9to_stringB5cxx11Ev Line | Count | Source | 89 | 48 | std::string to_string() const override { return std::to_string(value()); } |
_ZNK5doris12AtomicMetricImE9to_stringB5cxx11Ev Line | Count | Source | 89 | 1 | std::string to_string() const override { return std::to_string(value()); } |
|
90 | | |
91 | 58 | T value() const { return _value.load(); } _ZNK5doris12AtomicMetricIlE5valueEv Line | Count | Source | 91 | 55 | T value() const { return _value.load(); } |
_ZNK5doris12AtomicMetricImE5valueEv Line | Count | Source | 91 | 3 | T value() const { return _value.load(); } |
|
92 | | |
93 | 420k | void increment(const T& delta) { _value.fetch_add(delta); } _ZN5doris12AtomicMetricIlE9incrementERKl Line | Count | Source | 93 | 420k | void increment(const T& delta) { _value.fetch_add(delta); } |
_ZN5doris12AtomicMetricImE9incrementERKm Line | Count | Source | 93 | 35 | void increment(const T& delta) { _value.fetch_add(delta); } |
|
94 | | |
95 | 743 | void set_value(const T& value) { _value.store(value); } _ZN5doris12AtomicMetricIlE9set_valueERKl Line | Count | Source | 95 | 628 | void set_value(const T& value) { _value.store(value); } |
_ZN5doris12AtomicMetricImE9set_valueERKm Line | Count | Source | 95 | 115 | void set_value(const T& value) { _value.store(value); } |
|
96 | | |
97 | 1 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { |
98 | 1 | return rj::Value(value()); |
99 | 1 | } _ZNK5doris12AtomicMetricIlE13to_json_valueERN9rapidjson19MemoryPoolAllocatorINS2_12CrtAllocatorEEE Line | Count | Source | 97 | 1 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { | 98 | 1 | return rj::Value(value()); | 99 | 1 | } |
Unexecuted instantiation: _ZNK5doris12AtomicMetricImE13to_json_valueERN9rapidjson19MemoryPoolAllocatorINS2_12CrtAllocatorEEE |
100 | | |
101 | | protected: |
102 | | std::atomic<T> _value; |
103 | | }; |
104 | | |
105 | | template <typename T> |
106 | | class LockSimpleMetric : public Metric { |
107 | | public: |
108 | 56 | LockSimpleMetric() : _value(T()) {} |
109 | 50 | virtual ~LockSimpleMetric() {} |
110 | | |
111 | 5 | std::string to_string() const override { return std::to_string(value()); } |
112 | | |
113 | 9 | T value() const { |
114 | 9 | std::lock_guard<SpinLock> l(_lock); |
115 | 9 | return _value; |
116 | 9 | } |
117 | | |
118 | 1 | void increment(const T& delta) { |
119 | 1 | std::lock_guard<SpinLock> l(this->_lock); |
120 | 1 | _value += delta; |
121 | 1 | } |
122 | | |
123 | 4 | void set_value(const T& value) { |
124 | 4 | std::lock_guard<SpinLock> l(this->_lock); |
125 | 4 | _value = value; |
126 | 4 | } |
127 | | |
128 | 0 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { |
129 | 0 | return rj::Value(value()); |
130 | 0 | } |
131 | | |
132 | | protected: |
133 | | // We use spinlock instead of std::atomic is because atomic don't support |
134 | | // double's fetch_add |
135 | | // TODO(zc): If this is atomic is bottleneck, we change to thread local. |
136 | | // performance: on Intel(R) Xeon(R) CPU E5-2450 int64_t |
137 | | // original type: 2ns/op |
138 | | // single thread spinlock: 26ns/op |
139 | | // multiple thread(8) spinlock: 2500ns/op |
140 | | mutable SpinLock _lock; |
141 | | T _value; |
142 | | }; |
143 | | |
144 | | template <typename T> |
145 | | class CoreLocalCounter : public Metric { |
146 | | public: |
147 | 879 | CoreLocalCounter() {} _ZN5doris16CoreLocalCounterIlEC2Ev Line | Count | Source | 147 | 878 | CoreLocalCounter() {} |
_ZN5doris16CoreLocalCounterImEC2Ev Line | Count | Source | 147 | 1 | CoreLocalCounter() {} |
|
148 | 879 | virtual ~CoreLocalCounter() {} _ZN5doris16CoreLocalCounterIlED2Ev Line | Count | Source | 148 | 878 | virtual ~CoreLocalCounter() {} |
_ZN5doris16CoreLocalCounterImED2Ev Line | Count | Source | 148 | 1 | virtual ~CoreLocalCounter() {} |
|
149 | | |
150 | 36 | std::string to_string() const override { |
151 | 36 | std::stringstream ss; |
152 | 36 | ss << value(); |
153 | 36 | return ss.str(); |
154 | 36 | } _ZNK5doris16CoreLocalCounterIlE9to_stringB5cxx11Ev Line | Count | Source | 150 | 35 | std::string to_string() const override { | 151 | 35 | std::stringstream ss; | 152 | 35 | ss << value(); | 153 | 35 | return ss.str(); | 154 | 35 | } |
_ZNK5doris16CoreLocalCounterImE9to_stringB5cxx11Ev Line | Count | Source | 150 | 1 | std::string to_string() const override { | 151 | 1 | std::stringstream ss; | 152 | 1 | ss << value(); | 153 | 1 | return ss.str(); | 154 | 1 | } |
|
155 | | |
156 | 47 | T value() const { |
157 | 47 | T sum = 0; |
158 | 423 | for (int i = 0; i < _value.size(); ++i) { |
159 | 376 | sum += *_value.access_at_core(i); |
160 | 376 | } |
161 | 47 | return sum; |
162 | 47 | } _ZNK5doris16CoreLocalCounterIlE5valueEv Line | Count | Source | 156 | 44 | T value() const { | 157 | 44 | T sum = 0; | 158 | 396 | for (int i = 0; i < _value.size(); ++i) { | 159 | 352 | sum += *_value.access_at_core(i); | 160 | 352 | } | 161 | 44 | return sum; | 162 | 44 | } |
_ZNK5doris16CoreLocalCounterImE5valueEv Line | Count | Source | 156 | 3 | T value() const { | 157 | 3 | T sum = 0; | 158 | 27 | for (int i = 0; i < _value.size(); ++i) { | 159 | 24 | sum += *_value.access_at_core(i); | 160 | 24 | } | 161 | 3 | return sum; | 162 | 3 | } |
|
163 | | |
164 | 37.8k | void increment(const T& delta) { __sync_fetch_and_add(_value.access(), delta); } _ZN5doris16CoreLocalCounterIlE9incrementERKl Line | Count | Source | 164 | 37.8k | void increment(const T& delta) { __sync_fetch_and_add(_value.access(), delta); } |
_ZN5doris16CoreLocalCounterImE9incrementERKm Line | Count | Source | 164 | 1 | void increment(const T& delta) { __sync_fetch_and_add(_value.access(), delta); } |
|
165 | | |
166 | 5 | void reset() { _value.reset(); } |
167 | | |
168 | 5 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { |
169 | 5 | return rj::Value(value()); |
170 | 5 | } _ZNK5doris16CoreLocalCounterIlE13to_json_valueERN9rapidjson19MemoryPoolAllocatorINS2_12CrtAllocatorEEE Line | Count | Source | 168 | 5 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { | 169 | 5 | return rj::Value(value()); | 170 | 5 | } |
Unexecuted instantiation: _ZNK5doris16CoreLocalCounterImE13to_json_valueERN9rapidjson19MemoryPoolAllocatorINS2_12CrtAllocatorEEE |
171 | | |
172 | | protected: |
173 | | CoreLocalValue<T> _value; |
174 | | }; |
175 | | |
176 | | class HistogramMetric : public Metric { |
177 | | public: |
178 | 3 | HistogramMetric() {} |
179 | 3 | virtual ~HistogramMetric() {} |
180 | | |
181 | | HistogramMetric(const HistogramMetric&) = delete; |
182 | | HistogramMetric& operator=(const HistogramMetric&) = delete; |
183 | | |
184 | | void clear(); |
185 | | bool is_empty() const; |
186 | | void add(const uint64_t& value); |
187 | | void merge(const HistogramMetric& other); |
188 | | void set_histogram(const HistogramStat& stats); |
189 | | |
190 | 0 | uint64_t min() const { return _stats.min(); } |
191 | 0 | uint64_t max() const { return _stats.max(); } |
192 | 0 | uint64_t num() const { return _stats.num(); } |
193 | 0 | uint64_t sum() const { return _stats.sum(); } |
194 | | double median() const; |
195 | | double percentile(double p) const; |
196 | | double average() const; |
197 | | double standard_deviation() const; |
198 | | std::string to_string() const override; |
199 | | std::string to_prometheus(const std::string& display_name, const Labels& entity_labels, |
200 | | const Labels& metric_labels) const override; |
201 | | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override; |
202 | | |
203 | | protected: |
204 | | static std::map<std::string, double> _s_output_percentiles; |
205 | | mutable SpinLock _lock; |
206 | | HistogramStat _stats; |
207 | | }; |
208 | | |
209 | | template <typename T> |
210 | | class AtomicCounter : public AtomicMetric<T> { |
211 | | public: |
212 | 419 | AtomicCounter() {} |
213 | 413 | virtual ~AtomicCounter() {} |
214 | | }; |
215 | | |
216 | | template <typename T> |
217 | | class AtomicGauge : public AtomicMetric<T> { |
218 | | public: |
219 | 1.27k | AtomicGauge() : AtomicMetric<T>() {} _ZN5doris11AtomicGaugeIlEC2Ev Line | Count | Source | 219 | 966 | AtomicGauge() : AtomicMetric<T>() {} |
_ZN5doris11AtomicGaugeImEC2Ev Line | Count | Source | 219 | 308 | AtomicGauge() : AtomicMetric<T>() {} |
|
220 | 1.26k | virtual ~AtomicGauge() {} _ZN5doris11AtomicGaugeIlED2Ev Line | Count | Source | 220 | 960 | virtual ~AtomicGauge() {} |
_ZN5doris11AtomicGaugeImED2Ev Line | Count | Source | 220 | 308 | virtual ~AtomicGauge() {} |
|
221 | | }; |
222 | | |
223 | | template <typename T> |
224 | | class LockCounter : public LockSimpleMetric<T> { |
225 | | public: |
226 | 1 | LockCounter() : LockSimpleMetric<T>() {} |
227 | 1 | virtual ~LockCounter() {} |
228 | | }; |
229 | | |
230 | | // This can only used for trival type |
231 | | template <typename T> |
232 | | class LockGauge : public LockSimpleMetric<T> { |
233 | | public: |
234 | 55 | LockGauge() : LockSimpleMetric<T>() {} |
235 | 49 | virtual ~LockGauge() {} |
236 | | }; |
237 | | |
238 | | using IntCounter = CoreLocalCounter<int64_t>; |
239 | | using IntAtomicCounter = AtomicCounter<int64_t>; |
240 | | using UIntCounter = CoreLocalCounter<uint64_t>; |
241 | | using DoubleCounter = LockCounter<double>; |
242 | | using IntGauge = AtomicGauge<int64_t>; |
243 | | using UIntGauge = AtomicGauge<uint64_t>; |
244 | | using DoubleGauge = LockGauge<double>; |
245 | | |
246 | | using Labels = std::unordered_map<std::string, std::string>; |
247 | | struct MetricPrototype { |
248 | | public: |
249 | | MetricPrototype(MetricType type_, MetricUnit unit_, std::string name_, |
250 | | std::string description_ = "", std::string group_name_ = "", |
251 | | Labels labels_ = Labels(), bool is_core_metric_ = false) |
252 | | : is_core_metric(is_core_metric_), |
253 | | type(type_), |
254 | | unit(unit_), |
255 | | name(std::move(name_)), |
256 | | description(std::move(description_)), |
257 | | group_name(std::move(group_name_)), |
258 | 325 | labels(std::move(labels_)) {} |
259 | | |
260 | | std::string simple_name() const; |
261 | | std::string combine_name(const std::string& registry_name) const; |
262 | | std::string to_prometheus(const std::string& registry_name) const; |
263 | | |
264 | | bool is_core_metric; |
265 | | MetricType type; |
266 | | MetricUnit unit; |
267 | | std::string name; |
268 | | std::string description; |
269 | | std::string group_name; |
270 | | Labels labels; |
271 | | }; |
272 | | |
273 | | #define DEFINE_METRIC_PROTOTYPE(name, type, unit, desc, group, labels, core) \ |
274 | | ::doris::MetricPrototype METRIC_##name(type, unit, #name, desc, group, labels, core) |
275 | | |
276 | | #define DEFINE_COUNTER_METRIC_PROTOTYPE_2ARG(name, unit) \ |
277 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::COUNTER, unit, "", "", Labels(), false) |
278 | | |
279 | | #define DEFINE_COUNTER_METRIC_PROTOTYPE_3ARG(name, unit, desc) \ |
280 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::COUNTER, unit, desc, "", Labels(), false) |
281 | | |
282 | | #define DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(name, unit, desc, group, labels) \ |
283 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::COUNTER, unit, desc, #group, labels, false) |
284 | | |
285 | | #define DEFINE_GAUGE_METRIC_PROTOTYPE_2ARG(name, unit) \ |
286 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::GAUGE, unit, "", "", Labels(), false) |
287 | | |
288 | | #define DEFINE_GAUGE_CORE_METRIC_PROTOTYPE_2ARG(name, unit) \ |
289 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::GAUGE, unit, "", "", Labels(), true) |
290 | | |
291 | | #define DEFINE_GAUGE_METRIC_PROTOTYPE_3ARG(name, unit, desc) \ |
292 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::GAUGE, unit, desc, "", Labels(), false) |
293 | | |
294 | | #define DEFINE_GAUGE_METRIC_PROTOTYPE_5ARG(name, unit, desc, group, labels) \ |
295 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::GAUGE, unit, desc, #group, labels, false) |
296 | | |
297 | | #define DEFINE_HISTOGRAM_METRIC_PROTOTYPE_2ARG(name, unit) \ |
298 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::HISTOGRAM, unit, "", "", Labels(), false) |
299 | | |
300 | | #define INT_COUNTER_METRIC_REGISTER(entity, metric) \ |
301 | 928 | metric = (IntCounter*)(entity->register_metric<IntCounter>(&METRIC_##metric)) |
302 | | |
303 | | #define INT_GAUGE_METRIC_REGISTER(entity, metric) \ |
304 | 1.22k | metric = (IntGauge*)(entity->register_metric<IntGauge>(&METRIC_##metric)) |
305 | | |
306 | | #define INT_DOUBLE_METRIC_REGISTER(entity, metric) \ |
307 | 329 | metric = (DoubleGauge*)(entity->register_metric<DoubleGauge>(&METRIC_##metric)) |
308 | | |
309 | | #define INT_UGAUGE_METRIC_REGISTER(entity, metric) \ |
310 | 253 | metric = (UIntGauge*)(entity->register_metric<UIntGauge>(&METRIC_##metric)) |
311 | | |
312 | | #define INT_ATOMIC_COUNTER_METRIC_REGISTER(entity, metric) \ |
313 | 676 | metric = (IntAtomicCounter*)(entity->register_metric<IntAtomicCounter>(&METRIC_##metric)) |
314 | | |
315 | | #define HISTOGRAM_METRIC_REGISTER(entity, metric) \ |
316 | 1 | metric = (HistogramMetric*)(entity->register_metric<HistogramMetric>(&METRIC_##metric)) |
317 | | |
318 | | #define METRIC_DEREGISTER(entity, metric) entity->deregister_metric(&METRIC_##metric) |
319 | | |
320 | | // For 'metrics' in MetricEntity. |
321 | | struct MetricPrototypeHash { |
322 | 4.06k | size_t operator()(const MetricPrototype* metric_prototype) const { |
323 | 4.06k | return std::hash<std::string>()(metric_prototype->group_name.empty() |
324 | 4.06k | ? metric_prototype->name |
325 | 4.06k | : metric_prototype->group_name); |
326 | 4.06k | } |
327 | | }; |
328 | | |
329 | | struct MetricPrototypeEqualTo { |
330 | 3.63k | bool operator()(const MetricPrototype* first, const MetricPrototype* second) const { |
331 | 3.63k | return first->group_name == second->group_name && first->name == second->name; |
332 | 3.63k | } |
333 | | }; |
334 | | |
335 | | using MetricMap = std::unordered_map<const MetricPrototype*, Metric*, MetricPrototypeHash, |
336 | | MetricPrototypeEqualTo>; |
337 | | |
338 | | enum class MetricEntityType { kServer, kTablet }; |
339 | | |
340 | | class MetricEntity { |
341 | | public: |
342 | | MetricEntity(MetricEntityType type, const std::string& name, const Labels& labels) |
343 | 520 | : _type(type), _name(name), _labels(labels) {} |
344 | 517 | ~MetricEntity() { |
345 | 2.32k | for (auto& metric : _metrics) { |
346 | 2.32k | delete metric.second; |
347 | 2.32k | } |
348 | 517 | } |
349 | | |
350 | 955 | const std::string& name() const { return _name; } |
351 | | |
352 | | template <typename T> |
353 | 3.70k | Metric* register_metric(const MetricPrototype* metric_type) { |
354 | 3.70k | std::lock_guard<SpinLock> l(_lock); |
355 | 3.70k | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); |
356 | 3.70k | if (inserted_metric.second) { |
357 | | // If not exist, make a new metric pointer |
358 | 2.62k | inserted_metric.first->second = new T(); |
359 | 2.62k | } |
360 | 3.70k | return inserted_metric.first->second; |
361 | 3.70k | } _ZN5doris12MetricEntity15register_metricINS_16CoreLocalCounterIlEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 353 | 935 | Metric* register_metric(const MetricPrototype* metric_type) { | 354 | 935 | std::lock_guard<SpinLock> l(_lock); | 355 | 935 | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 356 | 935 | if (inserted_metric.second) { | 357 | | // If not exist, make a new metric pointer | 358 | 875 | inserted_metric.first->second = new T(); | 359 | 875 | } | 360 | 935 | return inserted_metric.first->second; | 361 | 935 | } |
_ZN5doris12MetricEntity15register_metricINS_11AtomicGaugeIlEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 353 | 1.22k | Metric* register_metric(const MetricPrototype* metric_type) { | 354 | 1.22k | std::lock_guard<SpinLock> l(_lock); | 355 | 1.22k | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 356 | 1.22k | if (inserted_metric.second) { | 357 | | // If not exist, make a new metric pointer | 358 | 965 | inserted_metric.first->second = new T(); | 359 | 965 | } | 360 | 1.22k | return inserted_metric.first->second; | 361 | 1.22k | } |
_ZN5doris12MetricEntity15register_metricINS_15HistogramMetricEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 353 | 3 | Metric* register_metric(const MetricPrototype* metric_type) { | 354 | 3 | std::lock_guard<SpinLock> l(_lock); | 355 | 3 | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 356 | 3 | if (inserted_metric.second) { | 357 | | // If not exist, make a new metric pointer | 358 | 3 | inserted_metric.first->second = new T(); | 359 | 3 | } | 360 | 3 | return inserted_metric.first->second; | 361 | 3 | } |
_ZN5doris12MetricEntity15register_metricINS_9LockGaugeIdEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 353 | 329 | Metric* register_metric(const MetricPrototype* metric_type) { | 354 | 329 | std::lock_guard<SpinLock> l(_lock); | 355 | 329 | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 356 | 329 | if (inserted_metric.second) { | 357 | | // If not exist, make a new metric pointer | 358 | 54 | inserted_metric.first->second = new T(); | 359 | 54 | } | 360 | 329 | return inserted_metric.first->second; | 361 | 329 | } |
_ZN5doris12MetricEntity15register_metricINS_11AtomicGaugeImEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 353 | 532 | Metric* register_metric(const MetricPrototype* metric_type) { | 354 | 532 | std::lock_guard<SpinLock> l(_lock); | 355 | 532 | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 356 | 532 | if (inserted_metric.second) { | 357 | | // If not exist, make a new metric pointer | 358 | 307 | inserted_metric.first->second = new T(); | 359 | 307 | } | 360 | 532 | return inserted_metric.first->second; | 361 | 532 | } |
_ZN5doris12MetricEntity15register_metricINS_13AtomicCounterIlEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 353 | 676 | Metric* register_metric(const MetricPrototype* metric_type) { | 354 | 676 | std::lock_guard<SpinLock> l(_lock); | 355 | 676 | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 356 | 676 | if (inserted_metric.second) { | 357 | | // If not exist, make a new metric pointer | 358 | 416 | inserted_metric.first->second = new T(); | 359 | 416 | } | 360 | 676 | return inserted_metric.first->second; | 361 | 676 | } |
|
362 | | |
363 | | void deregister_metric(const MetricPrototype* metric_type); |
364 | | Metric* get_metric(const std::string& name, const std::string& group_name = "") const; |
365 | | |
366 | | // Register a hook, this hook will called before get_metric is called |
367 | | void register_hook(const std::string& name, const std::function<void()>& hook); |
368 | | void deregister_hook(const std::string& name); |
369 | | void trigger_hook_unlocked(bool force) const; |
370 | | |
371 | | private: |
372 | | friend class MetricRegistry; |
373 | | friend struct MetricEntityHash; |
374 | | friend struct MetricEntityEqualTo; |
375 | | |
376 | | MetricEntityType _type; |
377 | | std::string _name; |
378 | | Labels _labels; |
379 | | |
380 | | mutable SpinLock _lock; |
381 | | MetricMap _metrics; |
382 | | std::map<std::string, std::function<void()>> _hooks; |
383 | | }; |
384 | | |
385 | | struct MetricEntityHash { |
386 | 954 | size_t operator()(const std::shared_ptr<MetricEntity> metric_entity) const { |
387 | 954 | return std::hash<std::string>()(metric_entity->name()); |
388 | 954 | } |
389 | | }; |
390 | | |
391 | | struct MetricEntityEqualTo { |
392 | | bool operator()(const std::shared_ptr<MetricEntity> first, |
393 | 623 | const std::shared_ptr<MetricEntity> second) const { |
394 | 623 | return first->_type == second->_type && first->_name == second->_name && |
395 | 623 | first->_labels == second->_labels; |
396 | 623 | } |
397 | | }; |
398 | | |
399 | | using EntityMetricsByType = |
400 | | std::unordered_map<const MetricPrototype*, std::vector<std::pair<MetricEntity*, Metric*>>, |
401 | | MetricPrototypeHash, MetricPrototypeEqualTo>; |
402 | | |
403 | | class MetricRegistry { |
404 | | public: |
405 | 6 | MetricRegistry(const std::string& name) : _name(name) {} |
406 | | ~MetricRegistry(); |
407 | | |
408 | | std::shared_ptr<MetricEntity> register_entity( |
409 | | const std::string& name, const Labels& labels = {}, |
410 | | MetricEntityType type = MetricEntityType::kServer); |
411 | | void deregister_entity(const std::shared_ptr<MetricEntity>& entity); |
412 | | std::shared_ptr<MetricEntity> get_entity(const std::string& name, const Labels& labels = {}, |
413 | | MetricEntityType type = MetricEntityType::kServer); |
414 | | |
415 | | void trigger_all_hooks(bool force) const; |
416 | | |
417 | | std::string to_prometheus(bool with_tablet_metrics = false) const; |
418 | | std::string to_json(bool with_tablet_metrics = false) const; |
419 | | std::string to_core_string() const; |
420 | | |
421 | | private: |
422 | | const std::string _name; |
423 | | |
424 | | mutable SpinLock _lock; |
425 | | // MetricEntity -> register count |
426 | | std::unordered_map<std::shared_ptr<MetricEntity>, int32_t, MetricEntityHash, |
427 | | MetricEntityEqualTo> |
428 | | _entities; |
429 | | }; |
430 | | |
431 | | } // namespace doris |