YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/metric_entity.h
Line
Count
Source (jump to first uncovered line)
1
//
2
// Copyright (c) YugaByte, Inc.
3
//
4
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5
// in compliance with the License.  You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software distributed under the License
10
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
// or implied.  See the License for the specific language governing permissions and limitations
12
// under the License.
13
//
14
//
15
16
#ifndef YB_UTIL_METRIC_ENTITY_H
17
#define YB_UTIL_METRIC_ENTITY_H
18
19
#include <functional>
20
#include <unordered_map>
21
22
#include "yb/gutil/callback_forward.h"
23
#include "yb/util/locks.h"
24
#include "yb/util/metrics_fwd.h"
25
#include "yb/util/status_fwd.h"
26
27
namespace yb {
28
29
class JsonWriter;
30
31
// Severity level used with metrics.
32
// Levels:
33
//   - Debug: Metrics that are diagnostically helpful but generally not monitored
34
//            during normal operation.
35
//   - Info: Generally useful metrics that operators always want to have available
36
//           but may not be monitored under normal circumstances.
37
//   - Warn: Metrics which can often indicate operational oddities, which may need
38
//           more investigation.
39
//
40
// The levels are ordered and lower levels include the levels above them:
41
//    Debug < Info < Warn
42
enum class MetricLevel {
43
  kDebug = 0,
44
  kInfo = 1,
45
  kWarn = 2
46
};
47
48
struct MetricJsonOptions {
49
  MetricJsonOptions() :
50
    include_raw_histograms(false),
51
    include_schema_info(false),
52
15.3k
    level(MetricLevel::kDebug) {
53
15.3k
  }
54
55
  // Include the raw histogram values and counts in the JSON output.
56
  // This allows consumers to do cross-server aggregation or window
57
  // data over time.
58
  // Default: false
59
  bool include_raw_histograms;
60
61
  // Include the metrics "schema" information (i.e description, label,
62
  // unit, etc).
63
  // Default: false
64
  bool include_schema_info;
65
66
  // Include the metrics at a level and above.
67
  // Default: debug
68
  MetricLevel level;
69
};
70
71
struct MetricPrometheusOptions {
72
  MetricPrometheusOptions() :
73
27
    level(MetricLevel::kDebug) {
74
27
  }
75
76
  // Include the metrics at a level and above.
77
  // Default: debug
78
  MetricLevel level;
79
80
  // Number of tables to include metrics for.
81
  uint32_t max_tables_metrics_breakdowns;
82
83
  // Regex for metrics that should always be included for all tables.
84
  std::string priority_regex;
85
};
86
87
class MetricEntityPrototype {
88
 public:
89
  explicit MetricEntityPrototype(const char* name);
90
  ~MetricEntityPrototype();
91
92
35.3M
  const char* name() const { return name_; }
93
94
  // Find or create an entity with the given ID within the provided 'registry'.
95
  scoped_refptr<MetricEntity> Instantiate(MetricRegistry* registry, const std::string& id) const;
96
97
  // If the entity already exists, then 'initial_attrs' will replace all existing
98
  // attributes.
99
  scoped_refptr<MetricEntity> Instantiate(
100
      MetricRegistry* registry,
101
      const std::string& id,
102
      const std::unordered_map<std::string, std::string>& initial_attrs) const;
103
104
 private:
105
  const char* const name_;
106
107
  DISALLOW_COPY_AND_ASSIGN(MetricEntityPrototype);
108
};
109
110
enum AggregationFunction {
111
  kSum,
112
  kMax
113
};
114
115
class MetricEntity : public RefCountedThreadSafe<MetricEntity> {
116
 public:
117
  typedef std::unordered_map<const MetricPrototype*, scoped_refptr<Metric> > MetricMap;
118
  typedef std::unordered_map<std::string, std::string> AttributeMap;
119
  typedef std::function<void (JsonWriter* writer, const MetricJsonOptions& opts)>
120
    ExternalJsonMetricsCb;
121
  typedef std::function<void (PrometheusWriter* writer, const MetricPrometheusOptions& opts)>
122
    ExternalPrometheusMetricsCb;
123
124
  scoped_refptr<Counter> FindOrCreateCounter(const CounterPrototype* proto);
125
  scoped_refptr<MillisLag> FindOrCreateMillisLag(const MillisLagPrototype* proto);
126
  scoped_refptr<AtomicMillisLag> FindOrCreateAtomicMillisLag(const MillisLagPrototype* proto);
127
  scoped_refptr<Histogram> FindOrCreateHistogram(const HistogramPrototype* proto);
128
  scoped_refptr<Histogram> FindOrCreateHistogram(std::unique_ptr<HistogramPrototype> proto);
129
130
  template<typename T>
131
  scoped_refptr<AtomicGauge<T>> FindOrCreateGauge(const GaugePrototype<T>* proto,
132
                                                  const T& initial_value);
133
134
  template<typename T>
135
  scoped_refptr<AtomicGauge<T>> FindOrCreateGauge(std::unique_ptr<GaugePrototype<T>> proto,
136
                                                  const T& initial_value);
137
138
  template<typename T>
139
  scoped_refptr<FunctionGauge<T> > FindOrCreateFunctionGauge(const GaugePrototype<T>* proto,
140
                                                             const Callback<T()>& function);
141
142
  // Return the metric instantiated from the given prototype, or NULL if none has been
143
  // instantiated. Primarily used by tests trying to read metric values.
144
  scoped_refptr<Metric> FindOrNull(const MetricPrototype& prototype) const;
145
146
1.15M
  const std::string& id() const { return id_; }
147
148
  // See MetricRegistry::WriteAsJson()
149
  CHECKED_STATUS WriteAsJson(JsonWriter* writer,
150
                     const std::vector<std::string>& requested_metrics,
151
                     const MetricJsonOptions& opts) const;
152
153
  CHECKED_STATUS WriteForPrometheus(PrometheusWriter* writer,
154
                     const std::vector<std::string>& requested_metrics,
155
                     const MetricPrometheusOptions& opts) const;
156
157
88
  const MetricMap& UnsafeMetricsMapForTests() const { return metric_map_; }
158
159
  // Mark that the given metric should never be retired until the metric
160
  // registry itself destructs. This is useful for system metrics such as
161
  // tcmalloc, etc, which should live as long as the process itself.
162
  void NeverRetire(const scoped_refptr<Metric>& metric);
163
164
  // Scan the metrics map for metrics needing retirement, removing them as necessary.
165
  //
166
  // Metrics are retired when they are no longer referenced outside of the metrics system
167
  // itself. Additionally, we only retire a metric that has been in this state for
168
  // at least FLAGS_metrics_retirement_age_ms milliseconds.
169
  void RetireOldMetrics();
170
171
  // Replaces all attributes for this entity.
172
  // Any attributes currently set, but not in 'attrs', are removed.
173
  void SetAttributes(const AttributeMap& attrs);
174
175
  // Set a particular attribute. Replaces any current value.
176
  void SetAttribute(const std::string& key, const std::string& val);
177
178
681k
  size_t num_metrics() const {
179
681k
    std::lock_guard<simple_spinlock> l(lock_);
180
681k
    return metric_map_.size();
181
681k
  }
182
183
0
  void AddExternalJsonMetricsCb(const ExternalJsonMetricsCb &external_metrics_cb) {
184
0
    std::lock_guard<simple_spinlock> l(lock_);
185
0
    external_json_metrics_cbs_.push_back(external_metrics_cb);
186
0
  }
187
188
0
  void AddExternalPrometheusMetricsCb(const ExternalPrometheusMetricsCb&external_metrics_cb) {
189
0
    std::lock_guard<simple_spinlock> l(lock_);
190
0
    external_prometheus_metrics_cbs_.push_back(external_metrics_cb);
191
0
  }
192
193
1.78M
  const MetricEntityPrototype& prototype() const { return *prototype_; }
194
195
  void Remove(const MetricPrototype* proto);
196
197
 private:
198
  friend class MetricRegistry;
199
  friend class RefCountedThreadSafe<MetricEntity>;
200
201
  MetricEntity(const MetricEntityPrototype* prototype, std::string id,
202
               AttributeMap attributes);
203
  ~MetricEntity();
204
205
  // Ensure that the given metric prototype is allowed to be instantiated
206
  // within this entity. This entity's type must match the expected entity
207
  // type defined within the metric prototype.
208
  void CheckInstantiation(const MetricPrototype* proto) const;
209
210
  const MetricEntityPrototype* const prototype_;
211
  const std::string id_;
212
213
  mutable simple_spinlock lock_;
214
215
  // Map from metric name to Metric object. Protected by lock_.
216
  MetricMap metric_map_;
217
218
  // The key/value attributes. Protected by lock_
219
  AttributeMap attributes_;
220
221
  // The set of metrics which should never be retired. Protected by lock_.
222
  std::vector<scoped_refptr<Metric> > never_retire_metrics_;
223
224
  // Callbacks fired each time WriteAsJson is called.
225
  std::vector<ExternalJsonMetricsCb> external_json_metrics_cbs_;
226
227
  // Callbacks fired each time WriteForPrometheus is called.
228
  std::vector<ExternalPrometheusMetricsCb> external_prometheus_metrics_cbs_;
229
};
230
231
void WriteRegistryAsJson(JsonWriter* writer);
232
233
} // namespace yb
234
235
#endif // YB_UTIL_METRIC_ENTITY_H