YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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.8k
    level(MetricLevel::kDebug) {
53
15.8k
  }
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
39
    level(MetricLevel::kDebug) {
74
39
  }
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
62.1M
  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<Counter> FindOrCreateCounter(std::unique_ptr<CounterPrototype> proto);
126
  scoped_refptr<MillisLag> FindOrCreateMillisLag(const MillisLagPrototype* proto);
127
  scoped_refptr<AtomicMillisLag> FindOrCreateAtomicMillisLag(const MillisLagPrototype* proto);
128
  scoped_refptr<Histogram> FindOrCreateHistogram(const HistogramPrototype* proto);
129
  scoped_refptr<Histogram> FindOrCreateHistogram(std::unique_ptr<HistogramPrototype> proto);
130
131
  template<typename T>
132
  scoped_refptr<AtomicGauge<T>> FindOrCreateGauge(const GaugePrototype<T>* proto,
133
                                                  const T& initial_value);
134
135
  template<typename T>
136
  scoped_refptr<AtomicGauge<T>> FindOrCreateGauge(std::unique_ptr<GaugePrototype<T>> proto,
137
                                                  const T& initial_value);
138
139
  template<typename T>
140
  scoped_refptr<FunctionGauge<T> > FindOrCreateFunctionGauge(const GaugePrototype<T>* proto,
141
                                                             const Callback<T()>& function);
142
143
  // Return the metric instantiated from the given prototype, or NULL if none has been
144
  // instantiated. Primarily used by tests trying to read metric values.
145
  scoped_refptr<Metric> FindOrNull(const MetricPrototype& prototype) const;
146
147
1.22M
  const std::string& id() const { return id_; }
148
149
  // See MetricRegistry::WriteAsJson()
150
  CHECKED_STATUS WriteAsJson(JsonWriter* writer,
151
                     const std::vector<std::string>& requested_metrics,
152
                     const MetricJsonOptions& opts) const;
153
154
  CHECKED_STATUS WriteForPrometheus(PrometheusWriter* writer,
155
                     const std::vector<std::string>& requested_metrics,
156
                     const MetricPrometheusOptions& opts) const;
157
158
  const MetricMap& UnsafeMetricsMapForTests() const { return metric_map_; }
159
160
  // Mark that the given metric should never be retired until the metric
161
  // registry itself destructs. This is useful for system metrics such as
162
  // tcmalloc, etc, which should live as long as the process itself.
163
  void NeverRetire(const scoped_refptr<Metric>& metric);
164
165
  // Scan the metrics map for metrics needing retirement, removing them as necessary.
166
  //
167
  // Metrics are retired when they are no longer referenced outside of the metrics system
168
  // itself. Additionally, we only retire a metric that has been in this state for
169
  // at least FLAGS_metrics_retirement_age_ms milliseconds.
170
  void RetireOldMetrics();
171
172
  // Replaces all attributes for this entity.
173
  // Any attributes currently set, but not in 'attrs', are removed.
174
  void SetAttributes(const AttributeMap& attrs);
175
176
  // Set a particular attribute. Replaces any current value.
177
  void SetAttribute(const std::string& key, const std::string& val);
178
179
1.05M
  size_t num_metrics() const {
180
1.05M
    std::lock_guard<simple_spinlock> l(lock_);
181
1.05M
    return metric_map_.size();
182
1.05M
  }
183
184
0
  void AddExternalJsonMetricsCb(const ExternalJsonMetricsCb &external_metrics_cb) {
185
0
    std::lock_guard<simple_spinlock> l(lock_);
186
0
    external_json_metrics_cbs_.push_back(external_metrics_cb);
187
0
  }
188
189
0
  void AddExternalPrometheusMetricsCb(const ExternalPrometheusMetricsCb&external_metrics_cb) {
190
0
    std::lock_guard<simple_spinlock> l(lock_);
191
0
    external_prometheus_metrics_cbs_.push_back(external_metrics_cb);
192
0
  }
193
194
2.61M
  const MetricEntityPrototype& prototype() const { return *prototype_; }
195
196
  void Remove(const MetricPrototype* proto);
197
198
 private:
199
  friend class MetricRegistry;
200
  friend class RefCountedThreadSafe<MetricEntity>;
201
202
  MetricEntity(const MetricEntityPrototype* prototype, std::string id,
203
               AttributeMap attributes);
204
  ~MetricEntity();
205
206
  // Ensure that the given metric prototype is allowed to be instantiated
207
  // within this entity. This entity's type must match the expected entity
208
  // type defined within the metric prototype.
209
  void CheckInstantiation(const MetricPrototype* proto) const;
210
211
  const MetricEntityPrototype* const prototype_;
212
  const std::string id_;
213
214
  mutable simple_spinlock lock_;
215
216
  // Map from metric name to Metric object. Protected by lock_.
217
  MetricMap metric_map_;
218
219
  // The key/value attributes. Protected by lock_
220
  AttributeMap attributes_;
221
222
  // The set of metrics which should never be retired. Protected by lock_.
223
  std::vector<scoped_refptr<Metric> > never_retire_metrics_;
224
225
  // Callbacks fired each time WriteAsJson is called.
226
  std::vector<ExternalJsonMetricsCb> external_json_metrics_cbs_;
227
228
  // Callbacks fired each time WriteForPrometheus is called.
229
  std::vector<ExternalPrometheusMetricsCb> external_prometheus_metrics_cbs_;
230
};
231
232
void WriteRegistryAsJson(JsonWriter* writer);
233
234
} // namespace yb
235
236
#endif // YB_UTIL_METRIC_ENTITY_H