YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/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
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
#ifndef YB_UTIL_METRICS_H
33
#define YB_UTIL_METRICS_H
34
35
/////////////////////////////////////////////////////
36
// YB Metrics
37
/////////////////////////////////////////////////////
38
//
39
// Summary
40
// ------------------------------------------------------------
41
//
42
// This API provides a basic set of metrics primitives along the lines of the Coda Hale's
43
// metrics library along with JSON formatted output of running metrics.
44
//
45
// The metrics system has a few main concepts in its data model:
46
//
47
// Metric Prototypes
48
// -----------------
49
// Every metric that may be emitted is constructed from a prototype. The prototype defines
50
// the name of the metric, the entity it is attached to, its type, its units, and a description.
51
//
52
// Metric prototypes are defined statically using the METRIC_DEFINE_*(...) macros. This
53
// allows us to easily enumerate a full list of every metric that might be emitted from a
54
// server, thus allowing auto-generation of metric metadata for integration with
55
// monitoring systems such as Prometheus.
56
//
57
// Metric Entity Prototypes
58
// ------------------------
59
// The other main type in the data model is the Metric Entity. The most basic entity is the
60
// "server" entity -- metrics such as memory usage, RPC rates, etc, are typically associated
61
// with the server as a whole.
62
//
63
// Users of the metrics framework can define more entity types using the
64
// METRIC_DEFINE_entity(...) macro.
65
//
66
// MetricEntity instances
67
// -----------------------
68
// Each defined Metric Entity Type serves as a prototype allowing instantiation of a
69
// MetricEntity object. Each instance then has its own unique set of metrics. For
70
// example, we define a Metric Entity Type called 'tablet', and the
71
// Tablet Server instantiates one MetricEntity instance per tablet that it hosts.
72
//
73
// MetricEntity instances are instantiated within a MetricRegistry, and each instance is
74
// expected to have a unique string identifier within that registry. To continue the
75
// example above, a tablet entity uses its tablet ID as its unique identifier. These
76
// identifiers are exposed to the operator and surfaced in monitoring tools.
77
//
78
// MetricEntity instances may also carry a key-value map of string attributes. These
79
// attributes are directly exposed to monitoring systems via the JSON output. Monitoring
80
// systems may use this information to allow hierarchical aggregation beteween entities,
81
// display them to the user, etc.
82
//
83
// Metric instances
84
// ----------------
85
// Given a MetricEntity instance and a Metric Prototype, one can instantiate a Metric
86
// instance. For example, the YB Tablet Server instantiates one MetricEntity instance
87
// for each tablet, and then instantiates the 'tablet_rows_inserted' prototype within that
88
// entity. Thus, each tablet then has a separate instance of the metric, allowing the end
89
// operator to track the metric on a per-tablet basis.
90
//
91
//
92
// Types of metrics
93
// ------------------------------------------------------------
94
// Gauge: Set or get a point-in-time value.
95
//  - string: Gauge for a string value.
96
//  - Primitive types (bool, int64_t/uint64_t, double): Lock-free gauges.
97
// Counter: Get, reset, increment or decrement an int64_t value.
98
// Histogram: Increment buckets of values segmented by configurable max and precision.
99
//
100
// Gauge vs. Counter
101
// ------------------------------------------------------------
102
//
103
// A Counter is a metric we expect to only monotonically increase. A
104
// Gauge is a metric that can decrease and increase. Use a Gauge to
105
// reflect a sample, e.g., the number of transaction in-flight at a
106
// given time; use a Counter when considering a metric over time,
107
// e.g., exposing the number of transactions processed since start to
108
// produce a metric for the number of transactions processed over some
109
// time period.
110
//
111
// The one exception to this rule is that occasionally it may be more convenient to
112
// implement a metric as a Gauge, even when it is logically a counter, due to Gauge's
113
// support for fetching metric values via a bound function. In that case, you can
114
// use the 'EXPOSE_AS_COUNTER' flag when defining the gauge prototype. For example:
115
//
116
// METRIC_DEFINE_gauge_uint64(server, threads_started,
117
//                            "Threads Started",
118
//                            yb::MetricUnit::kThreads,
119
//                            "Total number of threads started on this server",
120
//                            yb::EXPOSE_AS_COUNTER);
121
//
122
//
123
// Metrics ownership
124
// ------------------------------------------------------------
125
//
126
// Metrics are reference-counted, and one of the references is always held by a metrics
127
// entity itself. Users of metrics should typically hold a scoped_refptr to their metrics
128
// within class instances, so that they also hold a reference. The one exception to this
129
// is FunctionGauges: see the class documentation below for a typical Gauge ownership pattern.
130
//
131
// Because the metrics entity holds a reference to the metric, this means that metrics will
132
// not be immediately destructed when your class instance publishing them is destructed.
133
// This is on purpose: metrics are retained for a configurable time interval even after they
134
// are no longer being published. The purpose of this is to allow monitoring systems, which
135
// only poll metrics infrequently (eg once a minute) to see the last value of a metric whose
136
// owner was destructed in between two polls.
137
//
138
//
139
// Example usage for server-level metrics
140
// ------------------------------------------------------------
141
//
142
// 1) In your server class, define the top-level registry and the server entity:
143
//
144
//   MetricRegistry metric_registry_;
145
//   scoped_refptr<MetricEntity> metric_entity_;
146
//
147
// 2) In your server constructor/initialization, construct metric_entity_. This instance
148
//    will be plumbed through into other subsystems that want to register server-level
149
//    metrics.
150
//
151
//   metric_entity_ = METRIC_ENTITY_server.Instantiate(&registry_, "some server identifier)");
152
//
153
// 3) At the top of your .cc file where you want to emit a metric, define the metric prototype:
154
//
155
//   METRIC_DEFINE_counter(server, ping_requests, "Ping Requests", yb::MetricUnit::kRequests,
156
//       "Number of Ping() RPC requests this server has handled since start");
157
//
158
// 4) In your class where you want to emit metrics, define the metric instance itself:
159
//   scoped_refptr<Counter> ping_counter_;
160
//
161
// 5) In your class constructor, instantiate the metric based on the MetricEntity plumbed in:
162
//
163
//   MyClass(..., const scoped_refptr<MetricEntity>& metric_entity) :
164
//     ping_counter_(METRIC_ping_requests.Instantiate(metric_entity)) {
165
//   }
166
//
167
// 6) Where you want to change the metric value, just use the instance variable:
168
//
169
//   ping_counter_->IncrementBy(100);
170
//
171
//
172
// Example usage for custom entity metrics
173
// ------------------------------------------------------------
174
// Follow the same pattern as above, but also define a metric entity somewhere. For example:
175
//
176
// At the top of your CC file:
177
//
178
//   METRIC_DEFINE_entity(my_entity);
179
//   METRIC_DEFINE_counter(my_entity, ping_requests, "Ping Requests", yb::MetricUnit::kRequests,
180
//       "Number of Ping() RPC requests this particular entity has handled since start");
181
//
182
// In whatever class represents the entity:
183
//
184
//   entity_ = METRIC_ENTITY_my_entity.Instantiate(&registry_, my_entity_id);
185
//
186
// In whatever classes emit metrics:
187
//
188
//   scoped_refptr<Counter> ping_requests_ = METRIC_ping_requests.Instantiate(entity);
189
//   ping_requests_->Increment();
190
//
191
// NOTE: at runtime, the metrics system prevents you from instantiating a metric in the
192
// wrong entity type. This ensures that the metadata can fully describe the set of metric-entity
193
// relationships.
194
//
195
// Plumbing of MetricEntity and MetricRegistry objects
196
// ------------------------------------------------------------
197
// Generally, the rule of thumb to follow when plumbing through entities and registries is
198
// this: if you're creating new entities or you need to dump the registry contents
199
// (e.g. path handlers), pass in the registry. Otherwise, pass in the entity.
200
//
201
// ===========
202
// JSON output
203
// ===========
204
//
205
// The first-class output format for metrics is pretty-printed JSON.
206
// Such a format is relatively easy for humans and machines to read.
207
//
208
// The top level JSON object is an array, which contains one element per
209
// entity. Each entity is an object which has its type, id, and an array
210
// of metrics. Each metric contains its type, name, unit, description, value,
211
// etc.
212
// TODO: Output to HTML.
213
//
214
// Example JSON output:
215
//
216
// [
217
//     {
218
//         "type": "tablet",
219
//         "id": "e95e57ba8d4d48458e7c7d35020d4a46",
220
//         "attributes": {
221
//           "table_id": "12345",
222
//           "table_name": "my_table"
223
//         },
224
//         "metrics": [
225
//             {
226
//                 "type": "counter",
227
//                 "name": "log_reader_bytes_read",
228
//                 "label": "Log Reader Bytes Read",
229
//                 "unit": "bytes",
230
//                 "description": "Number of bytes read since tablet start",
231
//                 "value": 0
232
//             },
233
//             ...
234
//           ]
235
//      },
236
//      ...
237
// ]
238
//
239
/////////////////////////////////////////////////////
240
241
#include <stdint.h>
242
243
#include <cstdint>
244
#include <cstdlib>
245
#include <set>
246
#include <string>
247
248
#include <boost/preprocessor/cat.hpp>
249
#include <boost/preprocessor/stringize.hpp>
250
#include <gflags/gflags_declare.h>
251
252
#include <gtest/gtest_prod.h>
253
254
#include "yb/gutil/casts.h"
255
#include "yb/gutil/integral_types.h"
256
257
#include "yb/util/metrics_fwd.h"
258
#include "yb/util/status_fwd.h"
259
#include "yb/util/atomic.h"
260
#include "yb/util/jsonwriter.h"
261
#include "yb/util/metrics_writer.h"
262
#include "yb/util/monotime.h"
263
#include "yb/util/shared_lock.h"
264
#include "yb/util/striped64.h"
265
266
// Define a new entity type.
267
//
268
// The metrics subsystem itself defines the entity type 'server', but other
269
// entity types can be registered using this macro.
270
#define METRIC_DEFINE_entity(name)                               \
271
1
  ::yb::MetricEntityPrototype METRIC_ENTITY_##name(#name)
272
273
// Convenience macros to define metric prototypes.
274
// See the documentation at the top of this file for example usage.
275
#define METRIC_DEFINE_counter_with_level(entity, name, label, unit, desc, level)   \
276
  ::yb::CounterPrototype BOOST_PP_CAT(METRIC_, name)(                        \
277
      ::yb::MetricPrototype::CtorArgs(BOOST_PP_STRINGIZE(entity), \
278
                                      BOOST_PP_STRINGIZE(name), \
279
                                      label, \
280
                                      unit, \
281
                                      desc, \
282
                                      level))
283
284
#define METRIC_DEFINE_counter(entity, name, label, unit, desc)   \
285
  METRIC_DEFINE_counter_with_level(entity, name, label, unit, desc, yb::MetricLevel::kInfo)
286
287
#define METRIC_DEFINE_simple_counter(entity, name, label, unit) \
288
    METRIC_DEFINE_counter(entity, name, label, unit, label)
289
290
#define METRIC_DEFINE_lag_with_level(entity, name, label, desc, level, ...) \
291
  ::yb::MillisLagPrototype BOOST_PP_CAT(METRIC_, name)( \
292
      ::yb::MetricPrototype::CtorArgs(BOOST_PP_STRINGIZE(entity), \
293
                                      BOOST_PP_STRINGIZE(name), \
294
                                      label, \
295
                                      yb::MetricUnit::kMilliseconds, \
296
                                      desc, \
297
                                      level, \
298
                                      ## __VA_ARGS__))
299
300
#define METRIC_DEFINE_lag(entity, name, label, desc, ...) \
301
  METRIC_DEFINE_lag_with_level(entity, name, label, desc, yb::MetricLevel::kInfo, ## __VA_ARGS__)
302
303
#define METRIC_DEFINE_gauge(type, entity, name, label, unit, desc, level, ...) \
304
  ::yb::GaugePrototype<type> BOOST_PP_CAT(METRIC_, name)(         \
305
      ::yb::MetricPrototype::CtorArgs(BOOST_PP_STRINGIZE(entity), \
306
                                      BOOST_PP_STRINGIZE(name), \
307
                                      label, \
308
                                      unit, \
309
                                      desc, \
310
                                      level, \
311
                                      ## __VA_ARGS__))
312
313
#define METRIC_DEFINE_gauge_string(entity, name, label, unit, desc, ...) \
314
    METRIC_DEFINE_gauge(std::string, entity, name, label, unit, desc, \
315
        yb::MetricLevel::kInfo, ## __VA_ARGS__)
316
#define METRIC_DEFINE_gauge_bool(entity, name, label, unit, desc, ...) \
317
    METRIC_DEFINE_gauge(bool, entity, name, label, unit, desc, \
318
        yb::MetricLevel::kInfo, ## __VA_ARGS__)
319
#define METRIC_DEFINE_gauge_int32(entity, name, label, unit, desc, ...) \
320
    METRIC_DEFINE_gauge(int32_t, entity, name, label, unit, desc, \
321
        yb::MetricLevel::kInfo, ## __VA_ARGS__)
322
#define METRIC_DEFINE_gauge_uint32(entity, name, label, unit, desc, ...) \
323
    METRIC_DEFINE_gauge(uint32_t, entity, name, label, unit, desc, \
324
        yb::MetricLevel::kInfo, ## __VA_ARGS__)
325
#define METRIC_DEFINE_gauge_int64(entity, name, label, unit, desc, ...) \
326
    METRIC_DEFINE_gauge(int64, entity, name, label, unit, desc, \
327
        yb::MetricLevel::kInfo, ## __VA_ARGS__)
328
#define METRIC_DEFINE_gauge_uint64(entity, name, label, unit, desc, ...) \
329
    METRIC_DEFINE_gauge(uint64_t, entity, name, label, unit, desc, \
330
        yb::MetricLevel::kInfo, ## __VA_ARGS__)
331
#define METRIC_DEFINE_simple_gauge_uint64(entity, name, label, unit, ...) \
332
    METRIC_DEFINE_gauge(uint64_t, entity, name, label, unit, label, \
333
        yb::MetricLevel::kInfo, ## __VA_ARGS__)
334
#define METRIC_DEFINE_gauge_double(entity, name, label, unit, desc, ...) \
335
    METRIC_DEFINE_gauge(double, entity, name, label, unit, desc, \
336
        yb::MetricLevel::kInfo, ## __VA_ARGS__)
337
338
#define METRIC_DEFINE_histogram_with_percentiles(                              \
339
    entity, name, label, unit, desc, max_val, num_sig_digits)                  \
340
  ::yb::HistogramPrototype BOOST_PP_CAT(METRIC_, name)(                        \
341
      ::yb::MetricPrototype::CtorArgs(BOOST_PP_STRINGIZE(entity),              \
342
                                      BOOST_PP_STRINGIZE(name), label, unit,   \
343
                                      desc,                                    \
344
                                      yb::MetricLevel::kInfo),                 \
345
      max_val, num_sig_digits, yb::ExportPercentiles::kTrue)
346
347
#define METRIC_DEFINE_coarse_histogram(entity, name, label, unit, desc)        \
348
1
  ::yb::HistogramPrototype BOOST_PP_CAT(METRIC_, name)(                        \
349
1
      ::yb::MetricPrototype::CtorArgs(BOOST_PP_STRINGIZE(entity),              \
350
1
                                      BOOST_PP_STRINGIZE(name), label, unit,   \
351
1
                                      desc,                                    \
352
1
                                      yb::MetricLevel::kInfo),                 \
353
1
      2, 1, yb::ExportPercentiles::kFalse)
354
355
// The following macros act as forward declarations for entity types and metric prototypes.
356
#define METRIC_DECLARE_entity(name) \
357
  extern ::yb::MetricEntityPrototype METRIC_ENTITY_##name
358
#define METRIC_DECLARE_counter(name)                             \
359
  extern ::yb::CounterPrototype METRIC_##name
360
#define METRIC_DECLARE_lag(name) \
361
  extern ::yb::LagPrototype METRIC_##name
362
#define METRIC_DECLARE_gauge_string(name) \
363
  extern ::yb::GaugePrototype<std::string> METRIC_##name
364
#define METRIC_DECLARE_gauge_bool(name) \
365
  extern ::yb::GaugePrototype<bool> METRIC_##name
366
#define METRIC_DECLARE_gauge_int32(name) \
367
  extern ::yb::GaugePrototype<int32_t> METRIC_##name
368
#define METRIC_DECLARE_gauge_uint32(name) \
369
  extern ::yb::GaugePrototype<uint32_t> METRIC_##name
370
#define METRIC_DECLARE_gauge_int64(name) \
371
  extern ::yb::GaugePrototype<int64_t> METRIC_##name
372
#define METRIC_DECLARE_gauge_uint64(name) \
373
  extern ::yb::GaugePrototype<uint64_t> METRIC_##name
374
#define METRIC_DECLARE_gauge_double(name) \
375
  extern ::yb::GaugePrototype<double> METRIC_##name
376
#define METRIC_DECLARE_histogram(name) \
377
  extern ::yb::HistogramPrototype METRIC_##name
378
379
#if defined(__APPLE__)
380
#define METRIC_DEFINE_gauge_size(entity, name, label, unit, desc, ...) \
381
  ::yb::GaugePrototype<size_t> METRIC_##name(                    \
382
      ::yb::MetricPrototype::CtorArgs(#entity, #name, label, unit, desc, ## __VA_ARGS__))
383
#define METRIC_DECLARE_gauge_size(name) \
384
  extern ::yb::GaugePrototype<size_t> METRIC_##name
385
#else
386
#define METRIC_DEFINE_gauge_size METRIC_DEFINE_gauge_uint64
387
#define METRIC_DECLARE_gauge_size METRIC_DECLARE_gauge_uint64
388
#endif
389
390
// Forward-declare the generic 'server' entity type.
391
// We have to do this here below the forward declarations, but not
392
// in the yb namespace.
393
METRIC_DECLARE_entity(server);
394
395
namespace yb {
396
397
class JsonWriter;
398
399
// Unit types to be used with metrics.
400
// As additional units are required, add them to this enum and also to Name().
401
struct MetricUnit {
402
  enum Type {
403
    kCacheHits,
404
    kCacheQueries,
405
    kBytes,
406
    kRequests,
407
    kEntries,
408
    kRows,
409
    kCells,
410
    kConnections,
411
    kOperations,
412
    kProbes,
413
    kNanoseconds,
414
    kMicroseconds,
415
    kMilliseconds,
416
    kSeconds,
417
    kThreads,
418
    kTransactions,
419
    kUnits,
420
    kMaintenanceOperations,
421
    kBlocks,
422
    kLogBlockContainers,
423
    kTasks,
424
    kMessages,
425
    kContextSwitches,
426
    kFiles,
427
  };
428
  static const char* Name(Type unit);
429
};
430
431
class MetricType {
432
 public:
433
  enum Type { kGauge, kCounter, kHistogram, kLag };
434
  static const char* Name(Type t);
435
 private:
436
  static const char* const kGaugeType;
437
  static const char* const kCounterType;
438
  static const char* const kHistogramType;
439
};
440
441
// Base class to allow for putting all metrics into a single container.
442
// See documentation at the top of this file for information on metrics ownership.
443
class Metric : public RefCountedThreadSafe<Metric> {
444
 public:
445
  // All metrics must be able to render themselves as JSON.
446
  virtual CHECKED_STATUS WriteAsJson(JsonWriter* writer,
447
                                     const MetricJsonOptions& opts) const = 0;
448
449
  virtual CHECKED_STATUS WriteForPrometheus(
450
      PrometheusWriter* writer, const MetricEntity::AttributeMap& attr,
451
      const MetricPrometheusOptions& opts) const = 0;
452
453
3.42M
  const MetricPrototype* prototype() const { return prototype_; }
454
455
 protected:
456
  explicit Metric(const MetricPrototype* prototype);
457
  explicit Metric(std::unique_ptr<MetricPrototype> prototype);
458
  virtual ~Metric();
459
460
  std::unique_ptr<MetricPrototype> prototype_holder_;
461
  const MetricPrototype* const prototype_;
462
463
 private:
464
  friend class MetricEntity;
465
  friend class RefCountedThreadSafe<Metric>;
466
467
  // The time at which we should retire this metric if it is still un-referenced outside
468
  // of the metrics subsystem. If this metric is not due for retirement, this member is
469
  // uninitialized.
470
  MonoTime retire_time_;
471
472
  DISALLOW_COPY_AND_ASSIGN(Metric);
473
};
474
475
using MetricPtr = scoped_refptr<Metric>;
476
477
// Registry of all the metrics for a server.
478
//
479
// This aggregates the MetricEntity objects associated with the server.
480
class MetricRegistry {
481
 public:
482
  MetricRegistry();
483
  ~MetricRegistry();
484
485
  scoped_refptr<MetricEntity> FindOrCreateEntity(const MetricEntityPrototype* prototype,
486
                                                 const std::string& id,
487
                                                 const MetricEntity::AttributeMap& initial_attrs);
488
489
  // Writes metrics in this registry to 'writer'.
490
  //
491
  // 'requested_metrics' is a set of substrings to match metric names against,
492
  // where '*' matches all metrics.
493
  //
494
  // The string matching can either match an entity ID or a metric name.
495
  // If it matches an entity ID, then all metrics for that entity will be printed.
496
  //
497
  // See the MetricJsonOptions struct definition above for options changing the
498
  // output of this function.
499
  CHECKED_STATUS WriteAsJson(JsonWriter* writer,
500
                     const std::vector<std::string>& requested_metrics,
501
                     const MetricJsonOptions& opts) const;
502
503
  // Writes metrics in this registry to 'writer'.
504
  //
505
  // See the MetricPrometheusOptions struct definition above for options changing the
506
  // output of this function.
507
  CHECKED_STATUS WriteForPrometheus(PrometheusWriter* writer,
508
                     const MetricPrometheusOptions& opts) const;
509
  // Writes metrics in this registry to 'writer'.
510
  //
511
  // 'requested_metrics' is a set of substrings to match metric names against,
512
  // where '*' matches all metrics.
513
  //
514
  // The string matching can either match an entity ID or a metric name.
515
  // If it matches an entity ID, then all metrics for that entity will be printed.
516
  //
517
  // See the MetricPrometheusOptions struct definition above for options changing the
518
  // output of this function.
519
  CHECKED_STATUS WriteForPrometheus(PrometheusWriter* writer,
520
                     const std::vector<std::string>& requested_metrics,
521
                     const MetricPrometheusOptions& opts) const;
522
523
  // For each registered entity, retires orphaned metrics. If an entity has no more
524
  // metrics and there are no external references, entities are removed as well.
525
  //
526
  // See MetricEntity::RetireOldMetrics().
527
  void RetireOldMetrics();
528
529
  // Return the number of entities in this registry.
530
2
  size_t num_entities() const {
531
2
    std::lock_guard<simple_spinlock> l(lock_);
532
2
    return entities_.size();
533
2
  }
534
535
47.7k
  void tablets_shutdown_insert(std::string id) {
536
47.7k
    std::lock_guard<std::shared_timed_mutex> l(tablets_shutdown_lock_);
537
47.7k
    tablets_shutdown_.insert(id);
538
47.7k
  }
539
540
90.0k
  void tablets_shutdown_erase(std::string id) {
541
90.0k
    std::lock_guard<std::shared_timed_mutex> l(tablets_shutdown_lock_);
542
90.0k
    (void)tablets_shutdown_.erase(id);
543
90.0k
  }
544
545
511k
  bool tablets_shutdown_find(std::string id) const {
546
511k
    SharedLock<std::shared_timed_mutex> l(tablets_shutdown_lock_);
547
511k
    return tablets_shutdown_.find(id) != tablets_shutdown_.end();
548
511k
  }
549
550
 private:
551
  typedef std::unordered_map<std::string, scoped_refptr<MetricEntity> > EntityMap;
552
  EntityMap entities_;
553
554
  mutable std::shared_timed_mutex tablets_shutdown_lock_;
555
556
  // Set of tablets that have been shutdown. Protected by tablets_shutdown_lock_.
557
  std::set<std::string> tablets_shutdown_;
558
559
  // Returns whether a tablet has been shutdown.
560
  bool TabletHasBeenShutdown(const scoped_refptr<MetricEntity> entity) const;
561
562
  mutable simple_spinlock lock_;
563
  DISALLOW_COPY_AND_ASSIGN(MetricRegistry);
564
};
565
566
enum PrototypeFlags {
567
  // Flag which causes a Gauge prototype to expose itself as if it
568
  // were a counter.
569
  EXPOSE_AS_COUNTER = 1 << 0
570
};
571
572
class MetricPrototype {
573
 public:
574
  struct OptionalArgs {
575
    OptionalArgs(uint32_t flags = 0,
576
                 AggregationFunction aggregation_function = AggregationFunction::kSum)
577
      : flags_(flags),
578
22.0M
        aggregation_function_(aggregation_function) {
579
22.0M
    }
580
581
    const uint32_t flags_;
582
    const AggregationFunction aggregation_function_;
583
  };
584
585
  // Simple struct to aggregate the arguments common to all prototypes.
586
  // This makes constructor chaining a little less tedious.
587
  struct CtorArgs {
588
    CtorArgs(const char* entity_type,
589
             const char* name,
590
             const char* label,
591
             MetricUnit::Type unit,
592
             const char* description,
593
             MetricLevel level,
594
             OptionalArgs optional_args = OptionalArgs())
595
      : entity_type_(entity_type),
596
        name_(name),
597
        label_(label),
598
        unit_(unit),
599
        description_(description),
600
        level_(level),
601
        flags_(optional_args.flags_),
602
22.0M
        aggregation_function_(optional_args.aggregation_function_) {
603
22.0M
    }
604
605
    const char* const entity_type_;
606
    const char* const name_;
607
    const char* const label_;
608
    const MetricUnit::Type unit_;
609
    const char* const description_;
610
    const MetricLevel level_;
611
    const uint32_t flags_;
612
    const AggregationFunction aggregation_function_;
613
  };
614
615
32.2M
  const char* entity_type() const { return args_.entity_type_; }
616
193M
  const char* name() const { return args_.name_; }
617
35
  const char* label() const { return args_.label_; }
618
35
  MetricUnit::Type unit() const { return args_.unit_; }
619
42
  const char* description() const { return args_.description_; }
620
80.7M
  MetricLevel level() const { return args_.level_; }
621
56.2k
  AggregationFunction aggregation_function() const { return args_.aggregation_function_; }
622
  virtual MetricType::Type type() const = 0;
623
624
  // Writes the fields of this prototype to the given JSON writer.
625
  void WriteFields(JsonWriter* writer,
626
                   const MetricJsonOptions& opts) const;
627
628
11.5M
  virtual ~MetricPrototype() {}
629
630
 protected:
631
  explicit MetricPrototype(CtorArgs args);
632
633
  const CtorArgs args_;
634
635
 private:
636
  DISALLOW_COPY_AND_ASSIGN(MetricPrototype);
637
};
638
639
// A description of a Gauge.
640
template<typename T>
641
class GaugePrototype : public MetricPrototype {
642
 public:
643
  explicit GaugePrototype(const MetricPrototype::CtorArgs& args)
644
4.91M
    : MetricPrototype(args) {
645
4.91M
  }
_ZN2yb14GaugePrototypeIjEC2ERKNS_15MetricPrototype8CtorArgsE
Line
Count
Source
644
98.9k
    : MetricPrototype(args) {
645
98.9k
  }
_ZN2yb14GaugePrototypeIyEC2ERKNS_15MetricPrototype8CtorArgsE
Line
Count
Source
644
2.79M
    : MetricPrototype(args) {
645
2.79M
  }
_ZN2yb14GaugePrototypeIxEC2ERKNS_15MetricPrototype8CtorArgsE
Line
Count
Source
644
2.01M
    : MetricPrototype(args) {
645
2.01M
  }
_ZN2yb14GaugePrototypeIiEC2ERKNS_15MetricPrototype8CtorArgsE
Line
Count
Source
644
38
    : MetricPrototype(args) {
645
38
  }
646
647
  // Instantiate a "manual" gauge.
648
  scoped_refptr<AtomicGauge<T> > Instantiate(
649
      const scoped_refptr<MetricEntity>& entity,
650
9.57M
      const T& initial_value) const {
651
9.57M
    return entity->FindOrCreateGauge(this, initial_value);
652
9.57M
  }
_ZNK2yb14GaugePrototypeIjE11InstantiateERK13scoped_refptrINS_12MetricEntityEERKj
Line
Count
Source
650
102k
      const T& initial_value) const {
651
102k
    return entity->FindOrCreateGauge(this, initial_value);
652
102k
  }
_ZNK2yb14GaugePrototypeIyE11InstantiateERK13scoped_refptrINS_12MetricEntityEERKy
Line
Count
Source
650
8.88M
      const T& initial_value) const {
651
8.88M
    return entity->FindOrCreateGauge(this, initial_value);
652
8.88M
  }
_ZNK2yb14GaugePrototypeIiE11InstantiateERK13scoped_refptrINS_12MetricEntityEERKi
Line
Count
Source
650
2
      const T& initial_value) const {
651
2
    return entity->FindOrCreateGauge(this, initial_value);
652
2
  }
_ZNK2yb14GaugePrototypeIxE11InstantiateERK13scoped_refptrINS_12MetricEntityEERKx
Line
Count
Source
650
590k
      const T& initial_value) const {
651
590k
    return entity->FindOrCreateGauge(this, initial_value);
652
590k
  }
653
654
  // Instantiate a gauge that is backed by the given callback.
655
  scoped_refptr<FunctionGauge<T> > InstantiateFunctionGauge(
656
      const scoped_refptr<MetricEntity>& entity,
657
279k
      const Callback<T()>& function) const {
658
279k
    return entity->FindOrCreateFunctionGauge(this, function);
659
279k
  }
_ZNK2yb14GaugePrototypeIxE24InstantiateFunctionGaugeERK13scoped_refptrINS_12MetricEntityEERKNS_8CallbackIFxvEEE
Line
Count
Source
657
17.1k
      const Callback<T()>& function) const {
658
17.1k
    return entity->FindOrCreateFunctionGauge(this, function);
659
17.1k
  }
_ZNK2yb14GaugePrototypeIyE24InstantiateFunctionGaugeERK13scoped_refptrINS_12MetricEntityEERKNS_8CallbackIFyvEEE
Line
Count
Source
657
261k
      const Callback<T()>& function) const {
658
261k
    return entity->FindOrCreateFunctionGauge(this, function);
659
261k
  }
660
661
25
  virtual MetricType::Type type() const override {
662
25
    if (args_.flags_ & EXPOSE_AS_COUNTER) {
663
8
      return MetricType::kCounter;
664
17
    } else {
665
17
      return MetricType::kGauge;
666
17
    }
667
25
  }
Unexecuted instantiation: _ZNK2yb14GaugePrototypeIjE4typeEv
_ZNK2yb14GaugePrototypeIxE4typeEv
Line
Count
Source
661
1
  virtual MetricType::Type type() const override {
662
1
    if (args_.flags_ & EXPOSE_AS_COUNTER) {
663
0
      return MetricType::kCounter;
664
1
    } else {
665
1
      return MetricType::kGauge;
666
1
    }
667
1
  }
_ZNK2yb14GaugePrototypeIyE4typeEv
Line
Count
Source
661
22
  virtual MetricType::Type type() const override {
662
22
    if (args_.flags_ & EXPOSE_AS_COUNTER) {
663
8
      return MetricType::kCounter;
664
14
    } else {
665
14
      return MetricType::kGauge;
666
14
    }
667
22
  }
_ZNK2yb14GaugePrototypeIiE4typeEv
Line
Count
Source
661
2
  virtual MetricType::Type type() const override {
662
2
    if (args_.flags_ & EXPOSE_AS_COUNTER) {
663
0
      return MetricType::kCounter;
664
2
    } else {
665
2
      return MetricType::kGauge;
666
2
    }
667
2
  }
668
669
 private:
670
  DISALLOW_COPY_AND_ASSIGN(GaugePrototype);
671
};
672
673
// Abstract base class to provide point-in-time metric values.
674
class Gauge : public Metric {
675
 public:
676
  explicit Gauge(const MetricPrototype* prototype)
677
9.96M
      : Metric(prototype) {
678
9.96M
  }
679
680
  explicit Gauge(std::unique_ptr<MetricPrototype> prototype)
681
2.15M
      : Metric(std::move(prototype)) {
682
2.15M
  }
683
684
1.39M
  virtual ~Gauge() {}
685
  virtual CHECKED_STATUS WriteAsJson(JsonWriter* w,
686
                             const MetricJsonOptions& opts) const override;
687
 protected:
688
  virtual void WriteValue(JsonWriter* writer) const = 0;
689
 private:
690
  DISALLOW_COPY_AND_ASSIGN(Gauge);
691
};
692
693
// Gauge implementation for string that uses locks to ensure thread safety.
694
class StringGauge : public Gauge {
695
 public:
696
  StringGauge(const GaugePrototype<std::string>* proto,
697
              std::string initial_value);
698
  std::string value() const;
699
  void set_value(const std::string& value);
700
701
  CHECKED_STATUS WriteForPrometheus(
702
      PrometheusWriter* writer, const MetricEntity::AttributeMap& attr,
703
      const MetricPrometheusOptions& opts) const override;
704
 protected:
705
  virtual void WriteValue(JsonWriter* writer) const override;
706
 private:
707
  std::string value_;
708
  mutable simple_spinlock lock_;  // Guards value_
709
  DISALLOW_COPY_AND_ASSIGN(StringGauge);
710
};
711
712
// Lock-free implementation for types that are convertible to/from int64_t.
713
template <typename T>
714
class AtomicGauge : public Gauge {
715
 public:
716
  AtomicGauge(const GaugePrototype<T>* proto, T initial_value)
717
9.68M
      : Gauge(proto), value_(initial_value) {
718
9.68M
  }
_ZN2yb11AtomicGaugeIyEC2EPKNS_14GaugePrototypeIyEEy
Line
Count
Source
717
8.89M
      : Gauge(proto), value_(initial_value) {
718
8.89M
  }
_ZN2yb11AtomicGaugeIjEC2EPKNS_14GaugePrototypeIjEEj
Line
Count
Source
717
28.7k
      : Gauge(proto), value_(initial_value) {
718
28.7k
  }
_ZN2yb11AtomicGaugeIiEC2EPKNS_14GaugePrototypeIiEEi
Line
Count
Source
717
2
      : Gauge(proto), value_(initial_value) {
718
2
  }
_ZN2yb11AtomicGaugeIxEC2EPKNS_14GaugePrototypeIxEEx
Line
Count
Source
717
766k
      : Gauge(proto), value_(initial_value) {
718
766k
  }
719
720
  AtomicGauge(std::unique_ptr<GaugePrototype<T>> proto, T initial_value)
721
2.15M
      : Gauge(std::move(proto)), value_(initial_value) {}
_ZN2yb11AtomicGaugeIyEC2ENSt3__110unique_ptrINS_14GaugePrototypeIyEENS2_14default_deleteIS5_EEEEy
Line
Count
Source
721
369k
      : Gauge(std::move(proto)), value_(initial_value) {}
_ZN2yb11AtomicGaugeIxEC2ENSt3__110unique_ptrINS_14GaugePrototypeIxEENS2_14default_deleteIS5_EEEEx
Line
Count
Source
721
1.78M
      : Gauge(std::move(proto)), value_(initial_value) {}
722
723
86.5M
  T value() const {
724
86.5M
    return static_cast<T>(value_.Load(kMemOrderRelease));
725
86.5M
  }
_ZNK2yb11AtomicGaugeIxE5valueEv
Line
Count
Source
723
8.20M
  T value() const {
724
8.20M
    return static_cast<T>(value_.Load(kMemOrderRelease));
725
8.20M
  }
_ZNK2yb11AtomicGaugeIyE5valueEv
Line
Count
Source
723
78.2M
  T value() const {
724
78.2M
    return static_cast<T>(value_.Load(kMemOrderRelease));
725
78.2M
  }
_ZNK2yb11AtomicGaugeIjE5valueEv
Line
Count
Source
723
132k
  T value() const {
724
132k
    return static_cast<T>(value_.Load(kMemOrderRelease));
725
132k
  }
_ZNK2yb11AtomicGaugeIiE5valueEv
Line
Count
Source
723
8
  T value() const {
724
8
    return static_cast<T>(value_.Load(kMemOrderRelease));
725
8
  }
726
69.4M
  virtual void set_value(const T& value) {
727
69.4M
    value_.Store(static_cast<int64_t>(value), kMemOrderNoBarrier);
728
69.4M
  }
_ZN2yb11AtomicGaugeIyE9set_valueERKy
Line
Count
Source
726
7.68M
  virtual void set_value(const T& value) {
727
7.68M
    value_.Store(static_cast<int64_t>(value), kMemOrderNoBarrier);
728
7.68M
  }
_ZN2yb11AtomicGaugeIjE9set_valueERKj
Line
Count
Source
726
481k
  virtual void set_value(const T& value) {
727
481k
    value_.Store(static_cast<int64_t>(value), kMemOrderNoBarrier);
728
481k
  }
_ZN2yb11AtomicGaugeIiE9set_valueERKi
Line
Count
Source
726
8
  virtual void set_value(const T& value) {
727
8
    value_.Store(static_cast<int64_t>(value), kMemOrderNoBarrier);
728
8
  }
_ZN2yb11AtomicGaugeIxE9set_valueERKx
Line
Count
Source
726
61.2M
  virtual void set_value(const T& value) {
727
61.2M
    value_.Store(static_cast<int64_t>(value), kMemOrderNoBarrier);
728
61.2M
  }
729
120M
  void Increment() {
730
120M
    value_.IncrementBy(1, kMemOrderNoBarrier);
731
120M
  }
_ZN2yb11AtomicGaugeIxE9IncrementEv
Line
Count
Source
729
91.5M
  void Increment() {
730
91.5M
    value_.IncrementBy(1, kMemOrderNoBarrier);
731
91.5M
  }
_ZN2yb11AtomicGaugeIyE9IncrementEv
Line
Count
Source
729
28.7M
  void Increment() {
730
28.7M
    value_.IncrementBy(1, kMemOrderNoBarrier);
731
28.7M
  }
_ZN2yb11AtomicGaugeIjE9IncrementEv
Line
Count
Source
729
477k
  void Increment() {
730
477k
    value_.IncrementBy(1, kMemOrderNoBarrier);
731
477k
  }
732
1.92G
  virtual void IncrementBy(int64_t amount) {
733
1.92G
    value_.IncrementBy(amount, kMemOrderNoBarrier);
734
1.92G
  }
_ZN2yb11AtomicGaugeIyE11IncrementByEx
Line
Count
Source
732
1.03G
  virtual void IncrementBy(int64_t amount) {
733
1.03G
    value_.IncrementBy(amount, kMemOrderNoBarrier);
734
1.03G
  }
_ZN2yb11AtomicGaugeIjE11IncrementByEx
Line
Count
Source
732
474k
  virtual void IncrementBy(int64_t amount) {
733
474k
    value_.IncrementBy(amount, kMemOrderNoBarrier);
734
474k
  }
Unexecuted instantiation: _ZN2yb11AtomicGaugeIiE11IncrementByEx
_ZN2yb11AtomicGaugeIxE11IncrementByEx
Line
Count
Source
732
886M
  virtual void IncrementBy(int64_t amount) {
733
886M
    value_.IncrementBy(amount, kMemOrderNoBarrier);
734
886M
  }
735
123M
  void Decrement() {
736
123M
    IncrementBy(-1);
737
123M
  }
_ZN2yb11AtomicGaugeIxE9DecrementEv
Line
Count
Source
735
95.6M
  void Decrement() {
736
95.6M
    IncrementBy(-1);
737
95.6M
  }
_ZN2yb11AtomicGaugeIyE9DecrementEv
Line
Count
Source
735
27.2M
  void Decrement() {
736
27.2M
    IncrementBy(-1);
737
27.2M
  }
_ZN2yb11AtomicGaugeIjE9DecrementEv
Line
Count
Source
735
474k
  void Decrement() {
736
474k
    IncrementBy(-1);
737
474k
  }
738
13.0M
  void DecrementBy(int64_t amount) {
739
13.0M
    IncrementBy(-amount);
740
13.0M
  }
_ZN2yb11AtomicGaugeIxE11DecrementByEx
Line
Count
Source
738
12.9M
  void DecrementBy(int64_t amount) {
739
12.9M
    IncrementBy(-amount);
740
12.9M
  }
_ZN2yb11AtomicGaugeIyE11DecrementByEx
Line
Count
Source
738
173k
  void DecrementBy(int64_t amount) {
739
173k
    IncrementBy(-amount);
740
173k
  }
741
742
  CHECKED_STATUS WriteForPrometheus(
743
      PrometheusWriter* writer, const MetricEntity::AttributeMap& attr,
744
20.4k
      const MetricPrometheusOptions& opts) const override {
745
20.4k
    if (prototype_->level() < opts.level) {
746
0
      return Status::OK();
747
0
    }
748
749
20.4k
    return writer->WriteSingleEntry(attr, prototype_->name(), value(),
750
20.4k
                                    prototype()->aggregation_function());
751
20.4k
  }
_ZNK2yb11AtomicGaugeIyE18WriteForPrometheusEPNS_16PrometheusWriterERKNSt3__113unordered_mapINS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESB_NS4_4hashISB_EENS4_8equal_toISB_EENS9_INS4_4pairIKSB_SB_EEEEEERKNS_23MetricPrometheusOptionsE
Line
Count
Source
744
17.6k
      const MetricPrometheusOptions& opts) const override {
745
17.6k
    if (prototype_->level() < opts.level) {
746
0
      return Status::OK();
747
0
    }
748
749
17.6k
    return writer->WriteSingleEntry(attr, prototype_->name(), value(),
750
17.6k
                                    prototype()->aggregation_function());
751
17.6k
  }
_ZNK2yb11AtomicGaugeIjE18WriteForPrometheusEPNS_16PrometheusWriterERKNSt3__113unordered_mapINS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESB_NS4_4hashISB_EENS4_8equal_toISB_EENS9_INS4_4pairIKSB_SB_EEEEEERKNS_23MetricPrometheusOptionsE
Line
Count
Source
744
55
      const MetricPrometheusOptions& opts) const override {
745
55
    if (prototype_->level() < opts.level) {
746
0
      return Status::OK();
747
0
    }
748
749
55
    return writer->WriteSingleEntry(attr, prototype_->name(), value(),
750
55
                                    prototype()->aggregation_function());
751
55
  }
_ZNK2yb11AtomicGaugeIiE18WriteForPrometheusEPNS_16PrometheusWriterERKNSt3__113unordered_mapINS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESB_NS4_4hashISB_EENS4_8equal_toISB_EENS9_INS4_4pairIKSB_SB_EEEEEERKNS_23MetricPrometheusOptionsE
Line
Count
Source
744
8
      const MetricPrometheusOptions& opts) const override {
745
8
    if (prototype_->level() < opts.level) {
746
0
      return Status::OK();
747
0
    }
748
749
8
    return writer->WriteSingleEntry(attr, prototype_->name(), value(),
750
8
                                    prototype()->aggregation_function());
751
8
  }
_ZNK2yb11AtomicGaugeIxE18WriteForPrometheusEPNS_16PrometheusWriterERKNSt3__113unordered_mapINS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESB_NS4_4hashISB_EENS4_8equal_toISB_EENS9_INS4_4pairIKSB_SB_EEEEEERKNS_23MetricPrometheusOptionsE
Line
Count
Source
744
2.79k
      const MetricPrometheusOptions& opts) const override {
745
2.79k
    if (prototype_->level() < opts.level) {
746
0
      return Status::OK();
747
0
    }
748
749
2.79k
    return writer->WriteSingleEntry(attr, prototype_->name(), value(),
750
2.79k
                                    prototype()->aggregation_function());
751
2.79k
  }
752
753
 protected:
754
59.5M
  virtual void WriteValue(JsonWriter* writer) const override {
755
59.5M
    writer->Value(value());
756
59.5M
  }
_ZNK2yb11AtomicGaugeIyE10WriteValueEPNS_10JsonWriterE
Line
Count
Source
754
51.2M
  virtual void WriteValue(JsonWriter* writer) const override {
755
51.2M
    writer->Value(value());
756
51.2M
  }
_ZNK2yb11AtomicGaugeIjE10WriteValueEPNS_10JsonWriterE
Line
Count
Source
754
132k
  virtual void WriteValue(JsonWriter* writer) const override {
755
132k
    writer->Value(value());
756
132k
  }
Unexecuted instantiation: _ZNK2yb11AtomicGaugeIiE10WriteValueEPNS_10JsonWriterE
_ZNK2yb11AtomicGaugeIxE10WriteValueEPNS_10JsonWriterE
Line
Count
Source
754
8.19M
  virtual void WriteValue(JsonWriter* writer) const override {
755
8.19M
    writer->Value(value());
756
8.19M
  }
757
  AtomicInt<int64_t> value_;
758
 private:
759
  DISALLOW_COPY_AND_ASSIGN(AtomicGauge);
760
};
761
762
template <class T>
763
56.8M
void IncrementGauge(const scoped_refptr<AtomicGauge<T>>& gauge) {
764
56.8M
  if (gauge) {
765
55.2M
    gauge->Increment();
766
55.2M
  }
767
56.8M
}
_ZN2yb14IncrementGaugeIxEEvRK13scoped_refptrINS_11AtomicGaugeIT_EEE
Line
Count
Source
763
56.3M
void IncrementGauge(const scoped_refptr<AtomicGauge<T>>& gauge) {
764
56.3M
  if (gauge) {
765
54.7M
    gauge->Increment();
766
54.7M
  }
767
56.3M
}
_ZN2yb14IncrementGaugeIjEEvRK13scoped_refptrINS_11AtomicGaugeIT_EEE
Line
Count
Source
763
477k
void IncrementGauge(const scoped_refptr<AtomicGauge<T>>& gauge) {
764
477k
  if (gauge) {
765
477k
    gauge->Increment();
766
477k
  }
767
477k
}
768
769
template <class T>
770
56.3M
void DecrementGauge(const scoped_refptr<AtomicGauge<T>>& gauge) {
771
56.3M
  if (gauge) {
772
54.8M
    gauge->Decrement();
773
54.8M
  }
774
56.3M
}
_ZN2yb14DecrementGaugeIxEEvRK13scoped_refptrINS_11AtomicGaugeIT_EEE
Line
Count
Source
770
55.8M
void DecrementGauge(const scoped_refptr<AtomicGauge<T>>& gauge) {
771
55.8M
  if (gauge) {
772
54.3M
    gauge->Decrement();
773
54.3M
  }
774
55.8M
}
_ZN2yb14DecrementGaugeIjEEvRK13scoped_refptrINS_11AtomicGaugeIT_EEE
Line
Count
Source
770
474k
void DecrementGauge(const scoped_refptr<AtomicGauge<T>>& gauge) {
771
474k
  if (gauge) {
772
474k
    gauge->Decrement();
773
474k
  }
774
474k
}
775
776
// A Gauge that calls back to a function to get its value.
777
//
778
// This metric type should be used in cases where it is difficult to keep a running
779
// measure of a metric, but instead would like to compute the metric value whenever it is
780
// requested by a user.
781
//
782
// The lifecycle should be carefully considered when using a FunctionGauge. In particular,
783
// the bound function needs to always be safe to run -- so if it references a particular
784
// non-singleton class instance, the instance must out-live the function. Typically,
785
// the easiest way to ensure this is to use a FunctionGaugeDetacher (see above).
786
template <typename T>
787
class FunctionGauge : public Gauge {
788
 public:
789
243k
  T value() const {
790
243k
    std::lock_guard<simple_spinlock> l(lock_);
791
243k
    return function_.Run();
792
243k
  }
_ZNK2yb13FunctionGaugeIxE5valueEv
Line
Count
Source
789
15.3k
  T value() const {
790
15.3k
    std::lock_guard<simple_spinlock> l(lock_);
791
15.3k
    return function_.Run();
792
15.3k
  }
_ZNK2yb13FunctionGaugeIyE5valueEv
Line
Count
Source
789
227k
  T value() const {
790
227k
    std::lock_guard<simple_spinlock> l(lock_);
791
227k
    return function_.Run();
792
227k
  }
793
794
242k
  virtual void WriteValue(JsonWriter* writer) const override {
795
242k
    writer->Value(value());
796
242k
  }
_ZNK2yb13FunctionGaugeIxE10WriteValueEPNS_10JsonWriterE
Line
Count
Source
794
15.1k
  virtual void WriteValue(JsonWriter* writer) const override {
795
15.1k
    writer->Value(value());
796
15.1k
  }
_ZNK2yb13FunctionGaugeIyE10WriteValueEPNS_10JsonWriterE
Line
Count
Source
794
227k
  virtual void WriteValue(JsonWriter* writer) const override {
795
227k
    writer->Value(value());
796
227k
  }
797
798
  // Reset this FunctionGauge to return a specific value.
799
  // This should be used during destruction. If you want a settable
800
  // Gauge, use a normal Gauge instead of a FunctionGauge.
801
419
  void DetachToConstant(T v) {
802
419
    std::lock_guard<simple_spinlock> l(lock_);
803
419
    function_ = Bind(&FunctionGauge::Return, v);
804
419
  }
_ZN2yb13FunctionGaugeIxE16DetachToConstantEx
Line
Count
Source
801
133
  void DetachToConstant(T v) {
802
133
    std::lock_guard<simple_spinlock> l(lock_);
803
133
    function_ = Bind(&FunctionGauge::Return, v);
804
133
  }
_ZN2yb13FunctionGaugeIyE16DetachToConstantEy
Line
Count
Source
801
286
  void DetachToConstant(T v) {
802
286
    std::lock_guard<simple_spinlock> l(lock_);
803
286
    function_ = Bind(&FunctionGauge::Return, v);
804
286
  }
805
806
  // Get the current value of the gauge, and detach so that it continues to return this
807
  // value in perpetuity.
808
417
  void DetachToCurrentValue() {
809
417
    T last_value = value();
810
417
    DetachToConstant(last_value);
811
417
  }
_ZN2yb13FunctionGaugeIxE20DetachToCurrentValueEv
Line
Count
Source
808
131
  void DetachToCurrentValue() {
809
131
    T last_value = value();
810
131
    DetachToConstant(last_value);
811
131
  }
_ZN2yb13FunctionGaugeIyE20DetachToCurrentValueEv
Line
Count
Source
808
286
  void DetachToCurrentValue() {
809
286
    T last_value = value();
810
286
    DetachToConstant(last_value);
811
286
  }
812
813
  // Automatically detach this gauge when the given 'detacher' destructs.
814
  // After detaching, the metric will return 'value' in perpetuity.
815
1
  void AutoDetach(std::shared_ptr<void>* detacher, T value = T()) {
816
1
    auto old_value = *detacher;
817
1
    *detacher = std::shared_ptr<void>(nullptr,
818
1
        [self = make_scoped_refptr(this), value, old_value](auto) {
819
1
      self->DetachToConstant(value);
820
1
    });
821
1
  }
822
823
  // Automatically detach this gauge when the given 'detacher' destructs.
824
  // After detaching, the metric will return whatever its value was at the
825
  // time of detaching.
826
  //
827
  // Note that, when using this method, you should be sure that the FunctionGaugeDetacher
828
  // is destructed before any objects which are required by the gauge implementation.
829
  // In typical usage (see the FunctionGaugeDetacher class documentation) this means you
830
  // should declare the detacher member after all other class members that might be
831
  // accessed by the gauge function implementation.
832
51.4k
  void AutoDetachToLastValue(std::shared_ptr<void>* detacher) {
833
51.4k
    auto old_value = *detacher;
834
416
    *detacher = std::shared_ptr<void>(nullptr, [self = make_scoped_refptr(this), old_value](auto) {
835
416
      self->DetachToCurrentValue();
836
416
    });
_ZZN2yb13FunctionGaugeIxE21AutoDetachToLastValueEPNSt3__110shared_ptrIvEEENKUlT_E_clIDnEEDaS6_
Line
Count
Source
834
130
    *detacher = std::shared_ptr<void>(nullptr, [self = make_scoped_refptr(this), old_value](auto) {
835
130
      self->DetachToCurrentValue();
836
130
    });
_ZZN2yb13FunctionGaugeIyE21AutoDetachToLastValueEPNSt3__110shared_ptrIvEEENKUlT_E_clIDnEEDaS6_
Line
Count
Source
834
286
    *detacher = std::shared_ptr<void>(nullptr, [self = make_scoped_refptr(this), old_value](auto) {
835
286
      self->DetachToCurrentValue();
836
286
    });
837
51.4k
  }
_ZN2yb13FunctionGaugeIxE21AutoDetachToLastValueEPNSt3__110shared_ptrIvEE
Line
Count
Source
832
17.1k
  void AutoDetachToLastValue(std::shared_ptr<void>* detacher) {
833
17.1k
    auto old_value = *detacher;
834
17.1k
    *detacher = std::shared_ptr<void>(nullptr, [self = make_scoped_refptr(this), old_value](auto) {
835
17.1k
      self->DetachToCurrentValue();
836
17.1k
    });
837
17.1k
  }
_ZN2yb13FunctionGaugeIyE21AutoDetachToLastValueEPNSt3__110shared_ptrIvEE
Line
Count
Source
832
34.3k
  void AutoDetachToLastValue(std::shared_ptr<void>* detacher) {
833
34.3k
    auto old_value = *detacher;
834
34.3k
    *detacher = std::shared_ptr<void>(nullptr, [self = make_scoped_refptr(this), old_value](auto) {
835
34.3k
      self->DetachToCurrentValue();
836
34.3k
    });
837
34.3k
  }
838
839
  CHECKED_STATUS WriteForPrometheus(
840
      PrometheusWriter* writer, const MetricEntity::AttributeMap& attr,
841
304
      const MetricPrometheusOptions& opts) const override {
842
304
    if (prototype_->level() < opts.level) {
843
0
      return Status::OK();
844
0
    }
845
846
304
    return writer->WriteSingleEntry(attr, prototype_->name(), value(),
847
304
                                    prototype()->aggregation_function());
848
304
  }
_ZNK2yb13FunctionGaugeIxE18WriteForPrometheusEPNS_16PrometheusWriterERKNSt3__113unordered_mapINS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESB_NS4_4hashISB_EENS4_8equal_toISB_EENS9_INS4_4pairIKSB_SB_EEEEEERKNS_23MetricPrometheusOptionsE
Line
Count
Source
841
19
      const MetricPrometheusOptions& opts) const override {
842
19
    if (prototype_->level() < opts.level) {
843
0
      return Status::OK();
844
0
    }
845
846
19
    return writer->WriteSingleEntry(attr, prototype_->name(), value(),
847
19
                                    prototype()->aggregation_function());
848
19
  }
_ZNK2yb13FunctionGaugeIyE18WriteForPrometheusEPNS_16PrometheusWriterERKNSt3__113unordered_mapINS4_12basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESB_NS4_4hashISB_EENS4_8equal_toISB_EENS9_INS4_4pairIKSB_SB_EEEEEERKNS_23MetricPrometheusOptionsE
Line
Count
Source
841
285
      const MetricPrometheusOptions& opts) const override {
842
285
    if (prototype_->level() < opts.level) {
843
0
      return Status::OK();
844
0
    }
845
846
285
    return writer->WriteSingleEntry(attr, prototype_->name(), value(),
847
285
                                    prototype()->aggregation_function());
848
285
  }
849
850
 private:
851
  friend class MetricEntity;
852
853
  FunctionGauge(const GaugePrototype<T>* proto, Callback<T()> function)
854
279k
      : Gauge(proto), function_(std::move(function)) {}
_ZN2yb13FunctionGaugeIxEC2EPKNS_14GaugePrototypeIxEENS_8CallbackIFxvEEE
Line
Count
Source
854
17.1k
      : Gauge(proto), function_(std::move(function)) {}
_ZN2yb13FunctionGaugeIyEC2EPKNS_14GaugePrototypeIyEENS_8CallbackIFyvEEE
Line
Count
Source
854
261k
      : Gauge(proto), function_(std::move(function)) {}
855
856
6
  static T Return(T v) {
857
6
    return v;
858
6
  }
_ZN2yb13FunctionGaugeIxE6ReturnEx
Line
Count
Source
856
6
  static T Return(T v) {
857
6
    return v;
858
6
  }
Unexecuted instantiation: _ZN2yb13FunctionGaugeIyE6ReturnEy
859
860
  mutable simple_spinlock lock_;
861
  Callback<T()> function_;
862
  DISALLOW_COPY_AND_ASSIGN(FunctionGauge);
863
};
864
865
// Prototype for a counter.
866
class CounterPrototype : public MetricPrototype {
867
 public:
868
  explicit CounterPrototype(const MetricPrototype::CtorArgs& args)
869
12.7M
    : MetricPrototype(args) {
870
12.7M
  }
871
  scoped_refptr<Counter> Instantiate(const scoped_refptr<MetricEntity>& entity) const;
872
873
8
  virtual MetricType::Type type() const override { return MetricType::kCounter; }
874
875
 private:
876
  DISALLOW_COPY_AND_ASSIGN(CounterPrototype);
877
};
878
879
// Simple incrementing 64-bit integer.
880
// Only use Counters in cases that we expect the count to only increase. For example,
881
// a counter is appropriate for "number of transactions processed by the server",
882
// but not for "number of transactions currently in flight". Monitoring software
883
// knows that counters only increase and thus can compute rates over time, rates
884
// across multiple servers, etc, which aren't appropriate in the case of gauges.
885
class Counter : public Metric {
886
 public:
887
  int64_t value() const;
888
  void Increment();
889
  void IncrementBy(int64_t amount);
890
  virtual CHECKED_STATUS WriteAsJson(JsonWriter* w,
891
                             const MetricJsonOptions& opts) const override;
892
893
  CHECKED_STATUS WriteForPrometheus(
894
      PrometheusWriter* writer, const MetricEntity::AttributeMap& attr,
895
      const MetricPrometheusOptions& opts) const override;
896
897
 private:
898
  FRIEND_TEST(MetricsTest, SimpleCounterTest);
899
  FRIEND_TEST(MultiThreadedMetricsTest, CounterIncrementTest);
900
  friend class MetricEntity;
901
902
  explicit Counter(const CounterPrototype* proto);
903
904
  LongAdder value_;
905
  DISALLOW_COPY_AND_ASSIGN(Counter);
906
};
907
908
using CounterPtr = scoped_refptr<Counter>;
909
910
class MillisLagPrototype : public MetricPrototype {
911
 public:
912
27.1k
  explicit MillisLagPrototype(const MetricPrototype::CtorArgs& args) : MetricPrototype(args) {
913
27.1k
  }
914
  scoped_refptr<MillisLag> Instantiate(const scoped_refptr<MetricEntity>& entity) const;
915
916
2
  virtual MetricType::Type type() const override { return MetricType::kLag; }
917
918
 private:
919
  DISALLOW_COPY_AND_ASSIGN(MillisLagPrototype);
920
};
921
922
// Metric used to calculate the lag of a specific metric.
923
// The metric is in charge of updating the metric timestamp, and this method
924
// will be in charge of calculating the lag by doing now() - metric_timestamp_.
925
class MillisLag : public Metric {
926
 public:
927
3
  virtual int64_t lag_ms() const {
928
3
    return std::max(static_cast<int64_t>(0),
929
3
        static_cast<int64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
930
3
            std::chrono::system_clock::now().time_since_epoch()).count()) - timestamp_ms_);
931
3
  }
932
2
  virtual void UpdateTimestampInMilliseconds(int64_t timestamp) {
933
2
    timestamp_ms_ = timestamp;
934
2
  }
935
  virtual CHECKED_STATUS WriteAsJson(JsonWriter* w,
936
      const MetricJsonOptions& opts) const override;
937
  virtual CHECKED_STATUS WriteForPrometheus(
938
      PrometheusWriter* writer, const MetricEntity::AttributeMap& attr,
939
      const MetricPrometheusOptions& opts) const override;
940
941
 private:
942
  friend class MetricEntity;
943
  friend class AtomicMillisLag;
944
  friend class MetricsTest;
945
946
  explicit MillisLag(const MillisLagPrototype* proto);
947
948
  int64_t timestamp_ms_;
949
};
950
951
class AtomicMillisLag : public MillisLag {
952
 public:
953
  explicit AtomicMillisLag(const MillisLagPrototype* proto);
954
955
525k
  int64_t lag_ms() const override {
956
525k
    return std::max(static_cast<int64_t>(0),
957
525k
        static_cast<int64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
958
525k
            std::chrono::system_clock::now().time_since_epoch()).count()) -
959
525k
                atomic_timestamp_ms_.load(std::memory_order_acquire));
960
525k
  }
961
962
10.3M
  void UpdateTimestampInMilliseconds(int64_t timestamp) override {
963
10.3M
    atomic_timestamp_ms_.store(timestamp, std::memory_order_release);
964
10.3M
  }
965
966
  CHECKED_STATUS WriteAsJson(JsonWriter* w,
967
                             const MetricJsonOptions& opts) const override;
968
969
  CHECKED_STATUS WriteForPrometheus(
970
      PrometheusWriter* writer, const MetricEntity::AttributeMap& attr,
971
188
      const MetricPrometheusOptions& opts) const override {
972
188
    if (prototype_->level() < opts.level) {
973
0
      return Status::OK();
974
0
    }
975
976
188
    return writer->WriteSingleEntry(attr, prototype_->name(), this->lag_ms(),
977
188
                                    prototype()->aggregation_function());
978
188
  }
979
980
 protected:
981
  std::atomic<int64_t> atomic_timestamp_ms_;
982
 private:
983
  DISALLOW_COPY_AND_ASSIGN(AtomicMillisLag);
984
};
985
986
56.8M
inline void IncrementCounter(const CounterPtr& counter) {
987
56.8M
  if (counter) {
988
55.2M
    counter->Increment();
989
55.2M
  }
990
56.8M
}
991
992
121M
inline void IncrementCounterBy(const CounterPtr& counter, int64_t amount) {
993
121M
  if (counter) {
994
118M
    counter->IncrementBy(amount);
995
118M
  }
996
121M
}
997
998
YB_STRONGLY_TYPED_BOOL(ExportPercentiles);
999
1000
class HistogramPrototype : public MetricPrototype {
1001
 public:
1002
  HistogramPrototype(const MetricPrototype::CtorArgs& args,
1003
                     uint64_t max_trackable_value, int num_sig_digits,
1004
                     ExportPercentiles export_percentiles = ExportPercentiles::kFalse);
1005
  scoped_refptr<Histogram> Instantiate(const scoped_refptr<MetricEntity>& entity) const;
1006
1007
2.37M
  uint64_t max_trackable_value() const { return max_trackable_value_; }
1008
2.37M
  int num_sig_digits() const { return num_sig_digits_; }
1009
2.37M
  ExportPercentiles export_percentiles() const { return export_percentiles_; }
1010
1
  virtual MetricType::Type type() const override { return MetricType::kHistogram; }
1011
1012
 private:
1013
  const uint64_t max_trackable_value_;
1014
  const int num_sig_digits_;
1015
  const ExportPercentiles export_percentiles_;
1016
  DISALLOW_COPY_AND_ASSIGN(HistogramPrototype);
1017
};
1018
1019
class Histogram : public Metric {
1020
 public:
1021
  // Increment the histogram for the given value.
1022
  // 'value' must be non-negative.
1023
  void Increment(int64_t value);
1024
1025
  // Increment the histogram for the given value by the given amount.
1026
  // 'value' and 'amount' must be non-negative.
1027
  void IncrementBy(int64_t value, int64_t amount);
1028
1029
  // Return the total number of values added to the histogram (via Increment()
1030
  // or IncrementBy()).
1031
  uint64_t TotalCount() const;
1032
1033
  virtual CHECKED_STATUS WriteAsJson(JsonWriter* w,
1034
                             const MetricJsonOptions& opts) const override;
1035
1036
  CHECKED_STATUS WriteForPrometheus(
1037
      PrometheusWriter* writer, const MetricEntity::AttributeMap& attr,
1038
      const MetricPrometheusOptions& opts) const override;
1039
1040
  // Returns a snapshot of this histogram including the bucketed values and counts.
1041
  // Resets the bucketed counts, but not the total count/sum.
1042
  CHECKED_STATUS GetAndResetHistogramSnapshotPB(HistogramSnapshotPB* snapshot,
1043
                                const MetricJsonOptions& opts) const;
1044
1045
1046
  // Returns a pointer to the underlying histogram. The implementation of HdrHistogram
1047
  //   // is thread safe.
1048
28
  const HdrHistogram* histogram() const { return histogram_.get(); }
1049
1050
  uint64_t CountInBucketForValueForTests(uint64_t value) const;
1051
  uint64_t MinValueForTests() const;
1052
  uint64_t MaxValueForTests() const;
1053
  double MeanValueForTests() const;
1054
1055
 private:
1056
  FRIEND_TEST(MetricsTest, SimpleHistogramTest);
1057
  FRIEND_TEST(MetricsTest, ResetHistogramTest);
1058
  friend class MetricEntity;
1059
  explicit Histogram(const HistogramPrototype* proto);
1060
  explicit Histogram(std::unique_ptr<HistogramPrototype> proto, uint64_t highest_trackable_value,
1061
      int num_significant_digits, ExportPercentiles export_percentiles);
1062
1063
  const std::unique_ptr<HdrHistogram> histogram_;
1064
  const ExportPercentiles export_percentiles_;
1065
  DISALLOW_COPY_AND_ASSIGN(Histogram);
1066
};
1067
1068
using HistogramPtr = scoped_refptr<Histogram>;
1069
1070
239k
inline void IncrementHistogram(const scoped_refptr<Histogram>& histogram, int64_t value) {
1071
239k
  if (histogram) {
1072
239k
    histogram->Increment(value);
1073
239k
  }
1074
239k
}
1075
1076
YB_STRONGLY_TYPED_BOOL(Auto);
1077
1078
// Measures a duration while in scope. Adds this duration to specified histogram on destruction.
1079
class ScopedLatencyMetric {
1080
 public:
1081
  // If 'latency_hist' is NULL, this turns into a no-op.
1082
  // automatic - automatically update histogram when object is destroyed.
1083
  explicit ScopedLatencyMetric(const scoped_refptr<Histogram>& latency_hist,
1084
                               Auto automatic = Auto::kTrue);
1085
1086
  ScopedLatencyMetric(ScopedLatencyMetric&& rhs);
1087
  void operator=(ScopedLatencyMetric&& rhs);
1088
1089
  ScopedLatencyMetric(const ScopedLatencyMetric&) = delete;
1090
  void operator=(const ScopedLatencyMetric&) = delete;
1091
1092
  ~ScopedLatencyMetric();
1093
1094
  void Restart();
1095
  void Finish();
1096
1097
 private:
1098
  scoped_refptr<Histogram> latency_hist_;
1099
  MonoTime time_started_;
1100
  Auto auto_;
1101
};
1102
1103
////////////////////////////////////////////////////////////
1104
// Inline implementations of template methods
1105
////////////////////////////////////////////////////////////
1106
1107
template<typename T>
1108
inline scoped_refptr<AtomicGauge<T>> MetricEntity::FindOrCreateGauge(
1109
    const GaugePrototype<T>* proto,
1110
9.78M
    const T& initial_value) {
1111
9.78M
  CheckInstantiation(proto);
1112
9.78M
  std::lock_guard<simple_spinlock> l(lock_);
1113
9.78M
  auto it = metric_map_.find(proto);
1114
9.78M
  if (it == metric_map_.end()) {
1115
9.69M
    auto result = new AtomicGauge<T>(proto, initial_value);
1116
9.69M
    metric_map_.emplace(proto, result);
1117
9.69M
    return result;
1118
9.69M
  }
1119
86.5k
  return down_cast<AtomicGauge<T>*>(it->second.get());
1120
86.5k
}
_ZN2yb12MetricEntity17FindOrCreateGaugeIyEE13scoped_refptrINS_11AtomicGaugeIT_EEEPKNS_14GaugePrototypeIS4_EERKS4_
Line
Count
Source
1110
8.91M
    const T& initial_value) {
1111
8.91M
  CheckInstantiation(proto);
1112
8.91M
  std::lock_guard<simple_spinlock> l(lock_);
1113
8.91M
  auto it = metric_map_.find(proto);
1114
8.91M
  if (it == metric_map_.end()) {
1115
8.89M
    auto result = new AtomicGauge<T>(proto, initial_value);
1116
8.89M
    metric_map_.emplace(proto, result);
1117
8.89M
    return result;
1118
8.89M
  }
1119
11.9k
  return down_cast<AtomicGauge<T>*>(it->second.get());
1120
11.9k
}
_ZN2yb12MetricEntity17FindOrCreateGaugeIjEE13scoped_refptrINS_11AtomicGaugeIT_EEEPKNS_14GaugePrototypeIS4_EERKS4_
Line
Count
Source
1110
102k
    const T& initial_value) {
1111
102k
  CheckInstantiation(proto);
1112
102k
  std::lock_guard<simple_spinlock> l(lock_);
1113
102k
  auto it = metric_map_.find(proto);
1114
102k
  if (it == metric_map_.end()) {
1115
28.7k
    auto result = new AtomicGauge<T>(proto, initial_value);
1116
28.7k
    metric_map_.emplace(proto, result);
1117
28.7k
    return result;
1118
28.7k
  }
1119
73.4k
  return down_cast<AtomicGauge<T>*>(it->second.get());
1120
73.4k
}
_ZN2yb12MetricEntity17FindOrCreateGaugeIiEE13scoped_refptrINS_11AtomicGaugeIT_EEEPKNS_14GaugePrototypeIS4_EERKS4_
Line
Count
Source
1110
2
    const T& initial_value) {
1111
2
  CheckInstantiation(proto);
1112
2
  std::lock_guard<simple_spinlock> l(lock_);
1113
2
  auto it = metric_map_.find(proto);
1114
2
  if (it == metric_map_.end()) {
1115
2
    auto result = new AtomicGauge<T>(proto, initial_value);
1116
2
    metric_map_.emplace(proto, result);
1117
2
    return result;
1118
2
  }
1119
0
  return down_cast<AtomicGauge<T>*>(it->second.get());
1120
0
}
_ZN2yb12MetricEntity17FindOrCreateGaugeIxEE13scoped_refptrINS_11AtomicGaugeIT_EEEPKNS_14GaugePrototypeIS4_EERKS4_
Line
Count
Source
1110
768k
    const T& initial_value) {
1111
768k
  CheckInstantiation(proto);
1112
768k
  std::lock_guard<simple_spinlock> l(lock_);
1113
768k
  auto it = metric_map_.find(proto);
1114
768k
  if (it == metric_map_.end()) {
1115
766k
    auto result = new AtomicGauge<T>(proto, initial_value);
1116
766k
    metric_map_.emplace(proto, result);
1117
766k
    return result;
1118
766k
  }
1119
1.06k
  return down_cast<AtomicGauge<T>*>(it->second.get());
1120
1.06k
}
1121
1122
template<typename T>
1123
inline scoped_refptr<AtomicGauge<T> > MetricEntity::FindOrCreateGauge(
1124
    std::unique_ptr<GaugePrototype<T>> proto,
1125
2.15M
    const T& initial_value) {
1126
2.15M
  CheckInstantiation(proto.get());
1127
2.15M
  std::lock_guard<simple_spinlock> l(lock_);
1128
2.15M
  auto it = metric_map_.find(proto.get());
1129
2.15M
  if (it != metric_map_.end()) {
1130
0
    return down_cast<AtomicGauge<T>*>(it->second.get());
1131
0
  }
1132
2.15M
  auto result = new AtomicGauge<T>(std::move(proto), initial_value);
1133
2.15M
  metric_map_.emplace(result->prototype(), result);
1134
2.15M
  return result;
1135
2.15M
}
_ZN2yb12MetricEntity17FindOrCreateGaugeIyEE13scoped_refptrINS_11AtomicGaugeIT_EEENSt3__110unique_ptrINS_14GaugePrototypeIS4_EENS7_14default_deleteISA_EEEERKS4_
Line
Count
Source
1125
369k
    const T& initial_value) {
1126
369k
  CheckInstantiation(proto.get());
1127
369k
  std::lock_guard<simple_spinlock> l(lock_);
1128
369k
  auto it = metric_map_.find(proto.get());
1129
369k
  if (it != metric_map_.end()) {
1130
0
    return down_cast<AtomicGauge<T>*>(it->second.get());
1131
0
  }
1132
369k
  auto result = new AtomicGauge<T>(std::move(proto), initial_value);
1133
369k
  metric_map_.emplace(result->prototype(), result);
1134
369k
  return result;
1135
369k
}
_ZN2yb12MetricEntity17FindOrCreateGaugeIxEE13scoped_refptrINS_11AtomicGaugeIT_EEENSt3__110unique_ptrINS_14GaugePrototypeIS4_EENS7_14default_deleteISA_EEEERKS4_
Line
Count
Source
1125
1.78M
    const T& initial_value) {
1126
1.78M
  CheckInstantiation(proto.get());
1127
1.78M
  std::lock_guard<simple_spinlock> l(lock_);
1128
1.78M
  auto it = metric_map_.find(proto.get());
1129
1.78M
  if (it != metric_map_.end()) {
1130
0
    return down_cast<AtomicGauge<T>*>(it->second.get());
1131
0
  }
1132
1.78M
  auto result = new AtomicGauge<T>(std::move(proto), initial_value);
1133
1.78M
  metric_map_.emplace(result->prototype(), result);
1134
1.78M
  return result;
1135
1.78M
}
1136
1137
template<typename T>
1138
inline scoped_refptr<FunctionGauge<T> > MetricEntity::FindOrCreateFunctionGauge(
1139
    const GaugePrototype<T>* proto,
1140
279k
    const Callback<T()>& function) {
1141
279k
  CheckInstantiation(proto);
1142
279k
  std::lock_guard<simple_spinlock> l(lock_);
1143
279k
  auto it = metric_map_.find(proto);
1144
279k
  if (it != metric_map_.end()) {
1145
0
    return down_cast<FunctionGauge<T>*>(it->second.get());
1146
0
  }
1147
279k
  auto result = new FunctionGauge<T>(proto, function);
1148
279k
  metric_map_.emplace(proto, result);
1149
279k
  return result;
1150
279k
}
_ZN2yb12MetricEntity25FindOrCreateFunctionGaugeIxEE13scoped_refptrINS_13FunctionGaugeIT_EEEPKNS_14GaugePrototypeIS4_EERKNS_8CallbackIFS4_vEEE
Line
Count
Source
1140
17.1k
    const Callback<T()>& function) {
1141
17.1k
  CheckInstantiation(proto);
1142
17.1k
  std::lock_guard<simple_spinlock> l(lock_);
1143
17.1k
  auto it = metric_map_.find(proto);
1144
17.1k
  if (it != metric_map_.end()) {
1145
0
    return down_cast<FunctionGauge<T>*>(it->second.get());
1146
0
  }
1147
17.1k
  auto result = new FunctionGauge<T>(proto, function);
1148
17.1k
  metric_map_.emplace(proto, result);
1149
17.1k
  return result;
1150
17.1k
}
_ZN2yb12MetricEntity25FindOrCreateFunctionGaugeIyEE13scoped_refptrINS_13FunctionGaugeIT_EEEPKNS_14GaugePrototypeIS4_EERKNS_8CallbackIFS4_vEEE
Line
Count
Source
1140
261k
    const Callback<T()>& function) {
1141
261k
  CheckInstantiation(proto);
1142
261k
  std::lock_guard<simple_spinlock> l(lock_);
1143
261k
  auto it = metric_map_.find(proto);
1144
261k
  if (it != metric_map_.end()) {
1145
0
    return down_cast<FunctionGauge<T>*>(it->second.get());
1146
0
  }
1147
261k
  auto result = new FunctionGauge<T>(proto, function);
1148
261k
  metric_map_.emplace(proto, result);
1149
261k
  return result;
1150
261k
}
1151
1152
class OwningMetricCtorArgs {
1153
 public:
1154
  OwningMetricCtorArgs(
1155
      std::string entity_type,
1156
      std::string name,
1157
      std::string label,
1158
      MetricUnit::Type unit,
1159
      std::string description,
1160
      MetricLevel level,
1161
      uint32_t flags = 0)
1162
    : entity_type_(std::move(entity_type)), name_(std::move(name)), label_(std::move(label)),
1163
2.19M
      unit_(unit), description_(std::move(description)), level_(std::move(level)), flags_(flags) {}
1164
 protected:
1165
  std::string entity_type_;
1166
  std::string name_;
1167
  std::string label_;
1168
  MetricUnit::Type unit_;
1169
  std::string description_;
1170
  MetricLevel level_;
1171
  uint32_t flags_;
1172
};
1173
1174
template <class T>
1175
class OwningGaugePrototype : public OwningMetricCtorArgs, public GaugePrototype<T> {
1176
 public:
1177
  template <class... Args>
1178
  explicit OwningGaugePrototype(Args&&... args)
1179
      : OwningMetricCtorArgs(std::forward<Args>(args)...),
1180
        GaugePrototype<T>(MetricPrototype::CtorArgs(
1181
            OwningMetricCtorArgs::entity_type_.c_str(), OwningMetricCtorArgs::name_.c_str(),
1182
            OwningMetricCtorArgs::label_.c_str(), unit_, OwningMetricCtorArgs::description_.c_str(),
1183
2.15M
            OwningMetricCtorArgs::level_, flags_)) {}
_ZN2yb20OwningGaugePrototypeIyEC2IJRA7_KcRNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEESD_NS_10MetricUnit4TypeESD_NS_11MetricLevelENS_14PrototypeFlagsEEEEDpOT_
Line
Count
Source
1183
22.0k
            OwningMetricCtorArgs::level_, flags_)) {}
_ZN2yb20OwningGaugePrototypeIyEC2IJRA7_KcRNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEESD_NS_10MetricUnit4TypeESD_NS_11MetricLevelEEEEDpOT_
Line
Count
Source
1183
22.0k
            OwningMetricCtorArgs::level_, flags_)) {}
_ZN2yb20OwningGaugePrototypeIxEC2IJPKcNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEESB_NS_10MetricUnit4TypeESB_NS_11MetricLevelEEEEDpOT_
Line
Count
Source
1183
1.64M
            OwningMetricCtorArgs::level_, flags_)) {}
_ZN2yb20OwningGaugePrototypeIyEC2IJRA7_KcRNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEERKSC_NS_10MetricUnit4TypeESF_NS_11MetricLevelENS_14PrototypeFlagsEEEEDpOT_
Line
Count
Source
1183
324k
            OwningMetricCtorArgs::level_, flags_)) {}
_ZN2yb20OwningGaugePrototypeIxEC2IJPKcNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEERSB_NS_10MetricUnit4TypeESC_NS_11MetricLevelEEEEDpOT_
Line
Count
Source
1183
140k
            OwningMetricCtorArgs::level_, flags_)) {}
1184
};
1185
1186
class OwningHistogramPrototype : public OwningMetricCtorArgs, public HistogramPrototype {
1187
 public:
1188
  template <class... Args>
1189
  explicit OwningHistogramPrototype(const std::string& entity_type,
1190
                                    const std::string& name,
1191
                                    const std::string& label,
1192
                                    MetricUnit::Type unit,
1193
                                    const std::string& description,
1194
                                    MetricLevel level,
1195
                                    uint32_t flags,
1196
                                    uint64_t max_trackable_value,
1197
                                    int num_sig_digits,
1198
                                    ExportPercentiles export_percentiles =
1199
                                        ExportPercentiles::kFalse)
1200
      : OwningMetricCtorArgs(entity_type, name, label, unit, description, level, flags),
1201
        HistogramPrototype(MetricPrototype::CtorArgs(
1202
            OwningMetricCtorArgs::entity_type_.c_str(), OwningMetricCtorArgs::name_.c_str(),
1203
            OwningMetricCtorArgs::label_.c_str(), OwningMetricCtorArgs::unit_,
1204
            OwningMetricCtorArgs::description_.c_str(), OwningMetricCtorArgs::level_, flags_),
1205
43.7k
                           max_trackable_value, num_sig_digits, export_percentiles) {}
1206
};
1207
1208
// Replace specific chars with underscore to pass PrometheusNameRegex().
1209
void EscapeMetricNameForPrometheus(std::string *id);
1210
1211
} // namespace yb
1212
1213
#endif // YB_UTIL_METRICS_H