/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 | | |
39 | | namespace doris { |
40 | | |
41 | | namespace rj = RAPIDJSON_NAMESPACE; |
42 | | |
43 | | enum class MetricType { COUNTER, GAUGE, HISTOGRAM, SUMMARY, UNTYPED }; |
44 | | |
45 | | enum class MetricUnit { |
46 | | NANOSECONDS, |
47 | | MICROSECONDS, |
48 | | MILLISECONDS, |
49 | | SECONDS, |
50 | | BYTES, |
51 | | ROWS, |
52 | | PERCENT, |
53 | | REQUESTS, |
54 | | OPERATIONS, |
55 | | BLOCKS, |
56 | | ROWSETS, |
57 | | CONNECTIONS, |
58 | | PACKETS, |
59 | | NOUNIT, |
60 | | FILESYSTEM |
61 | | }; |
62 | | |
63 | | std::ostream& operator<<(std::ostream& os, MetricType type); |
64 | | const char* unit_name(MetricUnit unit); |
65 | | |
66 | | using Labels = std::unordered_map<std::string, std::string>; |
67 | | |
68 | | class Metric { |
69 | | public: |
70 | 5.26k | Metric() {} |
71 | 5.20k | virtual ~Metric() {} |
72 | | virtual std::string to_string() const = 0; |
73 | | virtual std::string to_prometheus(const std::string& display_name, const Labels& entity_labels, |
74 | | const Labels& metric_labels) const; |
75 | | virtual rj::Value to_json_value(rj::Document::AllocatorType& allocator) const = 0; |
76 | | |
77 | | private: |
78 | | friend class MetricRegistry; |
79 | | }; |
80 | | |
81 | | // Metric that only can increment |
82 | | template <typename T> |
83 | | class AtomicMetric : public Metric { |
84 | | public: |
85 | 3.31k | AtomicMetric() : _value(T()) {} _ZN5doris12AtomicMetricIlEC2Ev Line | Count | Source | 85 | 3.21k | AtomicMetric() : _value(T()) {} |
_ZN5doris12AtomicMetricImEC2Ev Line | Count | Source | 85 | 102 | AtomicMetric() : _value(T()) {} |
|
86 | 3.27k | virtual ~AtomicMetric() {} _ZN5doris12AtomicMetricIlED2Ev Line | Count | Source | 86 | 3.17k | virtual ~AtomicMetric() {} |
_ZN5doris12AtomicMetricImED2Ev Line | Count | Source | 86 | 102 | virtual ~AtomicMetric() {} |
|
87 | | |
88 | 262 | std::string to_string() const override { return std::to_string(value()); } _ZNK5doris12AtomicMetricIlE9to_stringB5cxx11Ev Line | Count | Source | 88 | 243 | std::string to_string() const override { return std::to_string(value()); } |
_ZNK5doris12AtomicMetricImE9to_stringB5cxx11Ev Line | Count | Source | 88 | 19 | std::string to_string() const override { return std::to_string(value()); } |
|
89 | | |
90 | 271 | T value() const { return _value.load(); } _ZNK5doris12AtomicMetricIlE5valueEv Line | Count | Source | 90 | 250 | T value() const { return _value.load(); } |
_ZNK5doris12AtomicMetricImE5valueEv Line | Count | Source | 90 | 21 | T value() const { return _value.load(); } |
|
91 | | |
92 | 40.7k | void increment(const T& delta) { _value.fetch_add(delta); } _ZN5doris12AtomicMetricIlE9incrementERKl Line | Count | Source | 92 | 40.7k | void increment(const T& delta) { _value.fetch_add(delta); } |
_ZN5doris12AtomicMetricImE9incrementERKm Line | Count | Source | 92 | 2 | void increment(const T& delta) { _value.fetch_add(delta); } |
|
93 | | |
94 | 671 | void set_value(const T& value) { _value.store(value); } _ZN5doris12AtomicMetricIlE9set_valueERKl Line | Count | Source | 94 | 556 | void set_value(const T& value) { _value.store(value); } |
_ZN5doris12AtomicMetricImE9set_valueERKm Line | Count | Source | 94 | 115 | void set_value(const T& value) { _value.store(value); } |
|
95 | | |
96 | 1 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { |
97 | 1 | return rj::Value(value()); |
98 | 1 | } _ZNK5doris12AtomicMetricIlE13to_json_valueERN9rapidjson19MemoryPoolAllocatorINS2_12CrtAllocatorEEE Line | Count | Source | 96 | 1 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { | 97 | 1 | return rj::Value(value()); | 98 | 1 | } |
Unexecuted instantiation: _ZNK5doris12AtomicMetricImE13to_json_valueERN9rapidjson19MemoryPoolAllocatorINS2_12CrtAllocatorEEE |
99 | | |
100 | | protected: |
101 | | std::atomic<T> _value; |
102 | | }; |
103 | | |
104 | | template <typename T> |
105 | | class LockSimpleMetric : public Metric { |
106 | | public: |
107 | 582 | LockSimpleMetric() : _value(T()) {} |
108 | 570 | virtual ~LockSimpleMetric() {} |
109 | | |
110 | 35 | std::string to_string() const override { return std::to_string(value()); } |
111 | | |
112 | 39 | T value() const { |
113 | 39 | std::lock_guard<std::mutex> l(_lock); |
114 | 39 | return _value; |
115 | 39 | } |
116 | | |
117 | 1 | void increment(const T& delta) { |
118 | 1 | std::lock_guard<std::mutex> l(this->_lock); |
119 | 1 | _value += delta; |
120 | 1 | } |
121 | | |
122 | 4 | void set_value(const T& value) { |
123 | 4 | std::lock_guard<std::mutex> l(this->_lock); |
124 | 4 | _value = value; |
125 | 4 | } |
126 | | |
127 | 0 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { |
128 | 0 | return rj::Value(value()); |
129 | 0 | } |
130 | | |
131 | | protected: |
132 | | // We use std::mutex instead of std::atomic is because atomic don't support |
133 | | // double's fetch_add |
134 | | // TODO(zc): If this is atomic is bottleneck, we change to thread local. |
135 | | // performance: on Intel(R) Xeon(R) CPU E5-2450 int64_t |
136 | | // original type: 2ns/op |
137 | | // single thread std::mutex: 26ns/op |
138 | | // multiple thread(8) std::mutex: 2500ns/op |
139 | | mutable std::mutex _lock; |
140 | | T _value; |
141 | | }; |
142 | | |
143 | | template <typename T> |
144 | | class CoreLocalCounter : public Metric { |
145 | | public: |
146 | 1.35k | CoreLocalCounter() {} _ZN5doris16CoreLocalCounterIlEC2Ev Line | Count | Source | 146 | 1.35k | CoreLocalCounter() {} |
_ZN5doris16CoreLocalCounterImEC2Ev Line | Count | Source | 146 | 1 | CoreLocalCounter() {} |
|
147 | 1.35k | virtual ~CoreLocalCounter() {} _ZN5doris16CoreLocalCounterIlED2Ev Line | Count | Source | 147 | 1.35k | virtual ~CoreLocalCounter() {} |
_ZN5doris16CoreLocalCounterImED2Ev Line | Count | Source | 147 | 1 | virtual ~CoreLocalCounter() {} |
|
148 | | |
149 | 250 | std::string to_string() const override { |
150 | 250 | std::stringstream ss; |
151 | 250 | ss << value(); |
152 | 250 | return ss.str(); |
153 | 250 | } _ZNK5doris16CoreLocalCounterIlE9to_stringB5cxx11Ev Line | Count | Source | 149 | 249 | std::string to_string() const override { | 150 | 249 | std::stringstream ss; | 151 | 249 | ss << value(); | 152 | 249 | return ss.str(); | 153 | 249 | } |
_ZNK5doris16CoreLocalCounterImE9to_stringB5cxx11Ev Line | Count | Source | 149 | 1 | std::string to_string() const override { | 150 | 1 | std::stringstream ss; | 151 | 1 | ss << value(); | 152 | 1 | return ss.str(); | 153 | 1 | } |
|
154 | | |
155 | 261 | T value() const { |
156 | 261 | T sum = 0; |
157 | 2.34k | for (int i = 0; i < _value.size(); ++i) { |
158 | 2.08k | sum += *_value.access_at_core(i); |
159 | 2.08k | } |
160 | 261 | return sum; |
161 | 261 | } _ZNK5doris16CoreLocalCounterIlE5valueEv Line | Count | Source | 155 | 258 | T value() const { | 156 | 258 | T sum = 0; | 157 | 2.32k | for (int i = 0; i < _value.size(); ++i) { | 158 | 2.06k | sum += *_value.access_at_core(i); | 159 | 2.06k | } | 160 | 258 | return sum; | 161 | 258 | } |
_ZNK5doris16CoreLocalCounterImE5valueEv Line | Count | Source | 155 | 3 | T value() const { | 156 | 3 | T sum = 0; | 157 | 27 | for (int i = 0; i < _value.size(); ++i) { | 158 | 24 | sum += *_value.access_at_core(i); | 159 | 24 | } | 160 | 3 | return sum; | 161 | 3 | } |
|
162 | | |
163 | 87.4k | void increment(const T& delta) { __sync_fetch_and_add(_value.access(), delta); } _ZN5doris16CoreLocalCounterIlE9incrementERKl Line | Count | Source | 163 | 87.4k | void increment(const T& delta) { __sync_fetch_and_add(_value.access(), delta); } |
_ZN5doris16CoreLocalCounterImE9incrementERKm Line | Count | Source | 163 | 1 | void increment(const T& delta) { __sync_fetch_and_add(_value.access(), delta); } |
|
164 | | |
165 | 5 | void reset() { _value.reset(); } |
166 | | |
167 | 5 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { |
168 | 5 | return rj::Value(value()); |
169 | 5 | } _ZNK5doris16CoreLocalCounterIlE13to_json_valueERN9rapidjson19MemoryPoolAllocatorINS2_12CrtAllocatorEEE Line | Count | Source | 167 | 5 | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override { | 168 | 5 | return rj::Value(value()); | 169 | 5 | } |
Unexecuted instantiation: _ZNK5doris16CoreLocalCounterImE13to_json_valueERN9rapidjson19MemoryPoolAllocatorINS2_12CrtAllocatorEEE |
170 | | |
171 | | protected: |
172 | | CoreLocalValue<T> _value; |
173 | | }; |
174 | | |
175 | | class HistogramMetric : public Metric { |
176 | | public: |
177 | 3 | HistogramMetric() {} |
178 | 3 | virtual ~HistogramMetric() {} |
179 | | |
180 | | HistogramMetric(const HistogramMetric&) = delete; |
181 | | HistogramMetric& operator=(const HistogramMetric&) = delete; |
182 | | |
183 | | void clear(); |
184 | | bool is_empty() const; |
185 | | void add(const uint64_t& value); |
186 | | void merge(const HistogramMetric& other); |
187 | | void set_histogram(const HistogramStat& stats); |
188 | | |
189 | 0 | uint64_t min() const { return _stats.min(); } |
190 | 0 | uint64_t max() const { return _stats.max(); } |
191 | 0 | uint64_t num() const { return _stats.num(); } |
192 | 0 | uint64_t sum() const { return _stats.sum(); } |
193 | | double median() const; |
194 | | double percentile(double p) const; |
195 | | double average() const; |
196 | | double standard_deviation() const; |
197 | | std::string to_string() const override; |
198 | | std::string to_prometheus(const std::string& display_name, const Labels& entity_labels, |
199 | | const Labels& metric_labels) const override; |
200 | | rj::Value to_json_value(rj::Document::AllocatorType& allocator) const override; |
201 | | |
202 | | protected: |
203 | | static std::map<std::string, double> _s_output_percentiles; |
204 | | mutable std::mutex _lock; |
205 | | HistogramStat _stats; |
206 | | }; |
207 | | |
208 | | template <typename T> |
209 | | class AtomicCounter : public AtomicMetric<T> { |
210 | | public: |
211 | 1.53k | AtomicCounter() {} |
212 | 1.50k | virtual ~AtomicCounter() {} |
213 | | }; |
214 | | |
215 | | template <typename T> |
216 | | class AtomicGauge : public AtomicMetric<T> { |
217 | | public: |
218 | 1.78k | AtomicGauge() : AtomicMetric<T>() {} _ZN5doris11AtomicGaugeIlEC2Ev Line | Count | Source | 218 | 1.68k | AtomicGauge() : AtomicMetric<T>() {} |
_ZN5doris11AtomicGaugeImEC2Ev Line | Count | Source | 218 | 102 | AtomicGauge() : AtomicMetric<T>() {} |
|
219 | 1.76k | virtual ~AtomicGauge() {} _ZN5doris11AtomicGaugeIlED2Ev Line | Count | Source | 219 | 1.66k | virtual ~AtomicGauge() {} |
_ZN5doris11AtomicGaugeImED2Ev Line | Count | Source | 219 | 102 | virtual ~AtomicGauge() {} |
|
220 | | }; |
221 | | |
222 | | template <typename T> |
223 | | class LockCounter : public LockSimpleMetric<T> { |
224 | | public: |
225 | 1 | LockCounter() : LockSimpleMetric<T>() {} |
226 | 1 | virtual ~LockCounter() {} |
227 | | }; |
228 | | |
229 | | // This can only used for trival type |
230 | | template <typename T> |
231 | | class LockGauge : public LockSimpleMetric<T> { |
232 | | public: |
233 | 581 | LockGauge() : LockSimpleMetric<T>() {} |
234 | 569 | virtual ~LockGauge() {} |
235 | | }; |
236 | | |
237 | | using IntCounter = CoreLocalCounter<int64_t>; |
238 | | using IntAtomicCounter = AtomicCounter<int64_t>; |
239 | | using UIntCounter = CoreLocalCounter<uint64_t>; |
240 | | using DoubleCounter = LockCounter<double>; |
241 | | using IntGauge = AtomicGauge<int64_t>; |
242 | | using UIntGauge = AtomicGauge<uint64_t>; |
243 | | using DoubleGauge = LockGauge<double>; |
244 | | |
245 | | using Labels = std::unordered_map<std::string, std::string>; |
246 | | struct MetricPrototype { |
247 | | public: |
248 | | MetricPrototype(MetricType type_, MetricUnit unit_, std::string name_, |
249 | | std::string description_ = "", std::string group_name_ = "", |
250 | | Labels labels_ = Labels(), bool is_core_metric_ = false) |
251 | | : is_core_metric(is_core_metric_), |
252 | | type(type_), |
253 | | unit(unit_), |
254 | | name(std::move(name_)), |
255 | | description(std::move(description_)), |
256 | | group_name(std::move(group_name_)), |
257 | 347 | labels(std::move(labels_)) {} |
258 | | |
259 | | std::string simple_name() const; |
260 | | std::string combine_name(const std::string& registry_name) const; |
261 | | std::string to_prometheus(const std::string& registry_name) const; |
262 | | |
263 | | bool is_core_metric; |
264 | | MetricType type; |
265 | | MetricUnit unit; |
266 | | std::string name; |
267 | | std::string description; |
268 | | std::string group_name; |
269 | | Labels labels; |
270 | | }; |
271 | | |
272 | | #define DEFINE_METRIC_PROTOTYPE(name, type, unit, desc, group, labels, core) \ |
273 | | ::doris::MetricPrototype METRIC_##name(type, unit, #name, desc, group, labels, core) |
274 | | |
275 | | #define DEFINE_COUNTER_METRIC_PROTOTYPE_2ARG(name, unit) \ |
276 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::COUNTER, unit, "", "", Labels(), false) |
277 | | |
278 | | #define DEFINE_COUNTER_METRIC_PROTOTYPE_3ARG(name, unit, desc) \ |
279 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::COUNTER, unit, desc, "", Labels(), false) |
280 | | |
281 | | #define DEFINE_COUNTER_METRIC_PROTOTYPE_5ARG(name, unit, desc, group, labels) \ |
282 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::COUNTER, unit, desc, #group, labels, false) |
283 | | |
284 | | #define DEFINE_GAUGE_METRIC_PROTOTYPE_2ARG(name, unit) \ |
285 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::GAUGE, unit, "", "", Labels(), false) |
286 | | |
287 | | #define DEFINE_GAUGE_CORE_METRIC_PROTOTYPE_2ARG(name, unit) \ |
288 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::GAUGE, unit, "", "", Labels(), true) |
289 | | |
290 | | #define DEFINE_GAUGE_METRIC_PROTOTYPE_3ARG(name, unit, desc) \ |
291 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::GAUGE, unit, desc, "", Labels(), false) |
292 | | |
293 | | #define DEFINE_GAUGE_METRIC_PROTOTYPE_5ARG(name, unit, desc, group, labels) \ |
294 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::GAUGE, unit, desc, #group, labels, false) |
295 | | |
296 | | #define DEFINE_HISTOGRAM_METRIC_PROTOTYPE_2ARG(name, unit) \ |
297 | | DEFINE_METRIC_PROTOTYPE(name, MetricType::HISTOGRAM, unit, "", "", Labels(), false) |
298 | | |
299 | | #define INT_COUNTER_METRIC_REGISTER(entity, metric) \ |
300 | 1.45k | metric = (IntCounter*)(entity->register_metric<IntCounter>(&METRIC_##metric)) |
301 | | |
302 | | #define INT_GAUGE_METRIC_REGISTER(entity, metric) \ |
303 | 1.79k | metric = (IntGauge*)(entity->register_metric<IntGauge>(&METRIC_##metric)) |
304 | | |
305 | | #define INT_DOUBLE_METRIC_REGISTER(entity, metric) \ |
306 | 654 | metric = (DoubleGauge*)(entity->register_metric<DoubleGauge>(&METRIC_##metric)) |
307 | | |
308 | | #define INT_UGAUGE_METRIC_REGISTER(entity, metric) \ |
309 | 8 | metric = (UIntGauge*)(entity->register_metric<UIntGauge>(&METRIC_##metric)) |
310 | | |
311 | | #define INT_ATOMIC_COUNTER_METRIC_REGISTER(entity, metric) \ |
312 | 1.67k | metric = (IntAtomicCounter*)(entity->register_metric<IntAtomicCounter>(&METRIC_##metric)) |
313 | | |
314 | | #define HISTOGRAM_METRIC_REGISTER(entity, metric) \ |
315 | 1 | metric = (HistogramMetric*)(entity->register_metric<HistogramMetric>(&METRIC_##metric)) |
316 | | |
317 | | #define METRIC_DEREGISTER(entity, metric) entity->deregister_metric(&METRIC_##metric) |
318 | | |
319 | | // For 'metrics' in MetricEntity. |
320 | | struct MetricPrototypeHash { |
321 | 7.01k | size_t operator()(const MetricPrototype* metric_prototype) const { |
322 | 7.01k | return std::hash<std::string>()(metric_prototype->group_name.empty() |
323 | 7.01k | ? metric_prototype->name |
324 | 7.01k | : metric_prototype->group_name); |
325 | 7.01k | } |
326 | | }; |
327 | | |
328 | | struct MetricPrototypeEqualTo { |
329 | 5.41k | bool operator()(const MetricPrototype* first, const MetricPrototype* second) const { |
330 | 5.41k | return first->group_name == second->group_name && first->name == second->name; |
331 | 5.41k | } |
332 | | }; |
333 | | |
334 | | using MetricMap = std::unordered_map<const MetricPrototype*, Metric*, MetricPrototypeHash, |
335 | | MetricPrototypeEqualTo>; |
336 | | |
337 | | enum class MetricEntityType { kServer, kTablet }; |
338 | | |
339 | | class MetricEntity { |
340 | | public: |
341 | | MetricEntity(MetricEntityType type, const std::string& name, const Labels& labels) |
342 | 764 | : _type(type), _name(name), _labels(labels) {} |
343 | 758 | ~MetricEntity() { |
344 | 5.10k | for (auto& metric : _metrics) { |
345 | 5.10k | delete metric.second; |
346 | 5.10k | } |
347 | 758 | } |
348 | | |
349 | 1.46k | const std::string& name() const { return _name; } |
350 | | |
351 | | template <typename T> |
352 | 5.99k | Metric* register_metric(const MetricPrototype* metric_type) { |
353 | 5.99k | std::lock_guard<std::mutex> l(_lock); |
354 | 5.99k | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); |
355 | 5.99k | if (inserted_metric.second) { |
356 | | // If not exist, make a new metric pointer |
357 | 5.25k | inserted_metric.first->second = new T(); |
358 | 5.25k | } |
359 | 5.99k | return inserted_metric.first->second; |
360 | 5.99k | } _ZN5doris12MetricEntity15register_metricINS_16CoreLocalCounterIlEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 352 | 1.45k | Metric* register_metric(const MetricPrototype* metric_type) { | 353 | 1.45k | std::lock_guard<std::mutex> l(_lock); | 354 | 1.45k | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 355 | 1.45k | if (inserted_metric.second) { | 356 | | // If not exist, make a new metric pointer | 357 | 1.35k | inserted_metric.first->second = new T(); | 358 | 1.35k | } | 359 | 1.45k | return inserted_metric.first->second; | 360 | 1.45k | } |
_ZN5doris12MetricEntity15register_metricINS_11AtomicGaugeIlEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 352 | 1.79k | Metric* register_metric(const MetricPrototype* metric_type) { | 353 | 1.79k | std::lock_guard<std::mutex> l(_lock); | 354 | 1.79k | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 355 | 1.79k | if (inserted_metric.second) { | 356 | | // If not exist, make a new metric pointer | 357 | 1.68k | inserted_metric.first->second = new T(); | 358 | 1.68k | } | 359 | 1.79k | return inserted_metric.first->second; | 360 | 1.79k | } |
_ZN5doris12MetricEntity15register_metricINS_15HistogramMetricEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 352 | 3 | Metric* register_metric(const MetricPrototype* metric_type) { | 353 | 3 | std::lock_guard<std::mutex> l(_lock); | 354 | 3 | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 355 | 3 | if (inserted_metric.second) { | 356 | | // If not exist, make a new metric pointer | 357 | 3 | inserted_metric.first->second = new T(); | 358 | 3 | } | 359 | 3 | return inserted_metric.first->second; | 360 | 3 | } |
_ZN5doris12MetricEntity15register_metricINS_9LockGaugeIdEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 352 | 654 | Metric* register_metric(const MetricPrototype* metric_type) { | 353 | 654 | std::lock_guard<std::mutex> l(_lock); | 354 | 654 | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 355 | 654 | if (inserted_metric.second) { | 356 | | // If not exist, make a new metric pointer | 357 | 580 | inserted_metric.first->second = new T(); | 358 | 580 | } | 359 | 654 | return inserted_metric.first->second; | 360 | 654 | } |
_ZN5doris12MetricEntity15register_metricINS_13AtomicCounterIlEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 352 | 1.67k | Metric* register_metric(const MetricPrototype* metric_type) { | 353 | 1.67k | std::lock_guard<std::mutex> l(_lock); | 354 | 1.67k | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 355 | 1.67k | if (inserted_metric.second) { | 356 | | // If not exist, make a new metric pointer | 357 | 1.52k | inserted_metric.first->second = new T(); | 358 | 1.52k | } | 359 | 1.67k | return inserted_metric.first->second; | 360 | 1.67k | } |
_ZN5doris12MetricEntity15register_metricINS_11AtomicGaugeImEEEEPNS_6MetricEPKNS_15MetricPrototypeE Line | Count | Source | 352 | 405 | Metric* register_metric(const MetricPrototype* metric_type) { | 353 | 405 | std::lock_guard<std::mutex> l(_lock); | 354 | 405 | auto inserted_metric = _metrics.insert(std::make_pair(metric_type, nullptr)); | 355 | 405 | if (inserted_metric.second) { | 356 | | // If not exist, make a new metric pointer | 357 | 101 | inserted_metric.first->second = new T(); | 358 | 101 | } | 359 | 405 | return inserted_metric.first->second; | 360 | 405 | } |
|
361 | | |
362 | | void deregister_metric(const MetricPrototype* metric_type); |
363 | | Metric* get_metric(const std::string& name, const std::string& group_name = "") const; |
364 | | |
365 | | // Register a hook, this hook will called before get_metric is called |
366 | | void register_hook(const std::string& name, const std::function<void()>& hook); |
367 | | void deregister_hook(const std::string& name); |
368 | | void trigger_hook_unlocked(bool force) const; |
369 | | |
370 | | private: |
371 | | friend class MetricRegistry; |
372 | | friend struct MetricEntityHash; |
373 | | friend struct MetricEntityEqualTo; |
374 | | |
375 | | MetricEntityType _type; |
376 | | std::string _name; |
377 | | Labels _labels; |
378 | | |
379 | | mutable std::mutex _lock; |
380 | | MetricMap _metrics; |
381 | | std::map<std::string, std::function<void()>> _hooks; |
382 | | }; |
383 | | |
384 | | struct MetricEntityHash { |
385 | 1.46k | size_t operator()(const std::shared_ptr<MetricEntity> metric_entity) const { |
386 | 1.46k | return std::hash<std::string>()(metric_entity->name()); |
387 | 1.46k | } |
388 | | }; |
389 | | |
390 | | struct MetricEntityEqualTo { |
391 | | bool operator()(const std::shared_ptr<MetricEntity> first, |
392 | 773 | const std::shared_ptr<MetricEntity> second) const { |
393 | 773 | return first->_type == second->_type && first->_name == second->_name && |
394 | 773 | first->_labels == second->_labels; |
395 | 773 | } |
396 | | }; |
397 | | |
398 | | using EntityMetricsByType = |
399 | | std::unordered_map<const MetricPrototype*, std::vector<std::pair<MetricEntity*, Metric*>>, |
400 | | MetricPrototypeHash, MetricPrototypeEqualTo>; |
401 | | |
402 | | class MetricRegistry { |
403 | | public: |
404 | 6 | MetricRegistry(const std::string& name) : _name(name) {} |
405 | | ~MetricRegistry(); |
406 | | |
407 | | std::shared_ptr<MetricEntity> register_entity( |
408 | | const std::string& name, const Labels& labels = {}, |
409 | | MetricEntityType type = MetricEntityType::kServer); |
410 | | void deregister_entity(const std::shared_ptr<MetricEntity>& entity); |
411 | | std::shared_ptr<MetricEntity> get_entity(const std::string& name, const Labels& labels = {}, |
412 | | MetricEntityType type = MetricEntityType::kServer); |
413 | | |
414 | | void trigger_all_hooks(bool force) const; |
415 | | |
416 | | std::string to_prometheus(bool with_tablet_metrics = false) const; |
417 | | std::string to_json(bool with_tablet_metrics = false) const; |
418 | | std::string to_core_string() const; |
419 | | |
420 | | private: |
421 | | const std::string _name; |
422 | | |
423 | | mutable std::mutex _lock; |
424 | | // MetricEntity -> register count |
425 | | std::unordered_map<std::shared_ptr<MetricEntity>, int32_t, MetricEntityHash, |
426 | | MetricEntityEqualTo> |
427 | | _entities; |
428 | | }; |
429 | | |
430 | | } // namespace doris |