YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/metrics_writer.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_METRICS_WRITER_H
17
#define YB_UTIL_METRICS_WRITER_H
18
19
#include <map>
20
21
#include "yb/util/metric_entity.h"
22
23
namespace yb {
24
25
class PrometheusWriter {
26
 public:
27
  explicit PrometheusWriter(std::stringstream* output);
28
29
  virtual ~PrometheusWriter();
30
31
  // Write to the a single metric entry for non-table level metrics.
32
  template <typename T>
33
  CHECKED_STATUS WriteSingleEntryNonTable(
34
2
      const MetricEntity::AttributeMap& attr, const std::string& name, const T& value) {
35
2
    auto it = attr.find("table_id");
36
2
    if (it != attr.end()) {
37
1
      return STATUS(
38
1
          InvalidArgument, "Expect no table_id in attr argument when calling this function.");
39
1
    }
40
41
1
    RETURN_NOT_OK(FlushSingleEntry(attr, name, value));
42
1
    return Status::OK();
43
1
  }
_ZN2yb16PrometheusWriter24WriteSingleEntryNonTableIjEENS_6StatusERKNSt3__113unordered_mapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS3_4hashISA_EENS3_8equal_toISA_EENS8_INS3_4pairIKSA_SA_EEEEEERSG_RKT_
Line
Count
Source
34
2
      const MetricEntity::AttributeMap& attr, const std::string& name, const T& value) {
35
2
    auto it = attr.find("table_id");
36
2
    if (it != attr.end()) {
37
1
      return STATUS(
38
1
          InvalidArgument, "Expect no table_id in attr argument when calling this function.");
39
1
    }
40
41
1
    RETURN_NOT_OK(FlushSingleEntry(attr, name, value));
42
1
    return Status::OK();
43
1
  }
Unexecuted instantiation: _ZN2yb16PrometheusWriter24WriteSingleEntryNonTableIiEENS_6StatusERKNSt3__113unordered_mapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS3_4hashISA_EENS3_8equal_toISA_EENS8_INS3_4pairIKSA_SA_EEEEEERSG_RKT_
Unexecuted instantiation: _ZN2yb16PrometheusWriter24WriteSingleEntryNonTableIyEENS_6StatusERKNSt3__113unordered_mapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS3_4hashISA_EENS3_8equal_toISA_EENS8_INS3_4pairIKSA_SA_EEEEEERSG_RKT_
44
45
  template<typename T>
46
  CHECKED_STATUS WriteSingleEntry(
47
      const MetricEntity::AttributeMap& attr, const std::string& name, const T& value,
48
56.2k
      AggregationFunction aggregation_function) {
49
56.2k
    auto it = attr.find("table_id");
50
56.2k
    if (it != attr.end()) {
51
      // For tablet level metrics, we roll up on the table level.
52
23.3k
      if (per_table_attributes_.find(it->second) == per_table_attributes_.end()) {
53
        // If it's the first time we see this table, create the aggregate structures.
54
27
        per_table_attributes_[it->second] = attr;
55
27
        per_table_values_[it->second][name] = value;
56
23.3k
      } else {
57
23.3k
        switch (aggregation_function) {
58
23.1k
          case kSum:
59
23.1k
            per_table_values_[it->second][name] += value;
60
23.1k
            break;
61
172
          case kMax:
62
            // If we have a new max, also update the metadata so that it matches correctly.
63
172
            if (static_cast<double>(value) > per_table_values_[it->second][name]) {
64
29
              per_table_attributes_[it->second] = attr;
65
29
              per_table_values_[it->second][name] = value;
66
29
            }
67
172
            break;
68
0
          default:
69
0
            InvalidAggregationFunction(aggregation_function);
70
0
            break;
71
32.8k
        }
72
32.8k
      }
73
32.8k
    } else {
74
      // For non-tablet level metrics, export them directly.
75
32.8k
      RETURN_NOT_OK(FlushSingleEntry(attr, name, value));
76
32.8k
    }
77
56.2k
    return Status::OK();
78
56.2k
  }
_ZN2yb16PrometheusWriter16WriteSingleEntryIyEENS_6StatusERKNSt3__113unordered_mapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS3_4hashISA_EENS3_8equal_toISA_EENS8_INS3_4pairIKSA_SA_EEEEEERSG_RKT_NS_19AggregationFunctionE
Line
Count
Source
48
36.7k
      AggregationFunction aggregation_function) {
49
36.7k
    auto it = attr.find("table_id");
50
36.7k
    if (it != attr.end()) {
51
      // For tablet level metrics, we roll up on the table level.
52
18.1k
      if (per_table_attributes_.find(it->second) == per_table_attributes_.end()) {
53
        // If it's the first time we see this table, create the aggregate structures.
54
19
        per_table_attributes_[it->second] = attr;
55
19
        per_table_values_[it->second][name] = value;
56
18.0k
      } else {
57
18.0k
        switch (aggregation_function) {
58
18.0k
          case kSum:
59
18.0k
            per_table_values_[it->second][name] += value;
60
18.0k
            break;
61
0
          case kMax:
62
            // If we have a new max, also update the metadata so that it matches correctly.
63
0
            if (static_cast<double>(value) > per_table_values_[it->second][name]) {
64
0
              per_table_attributes_[it->second] = attr;
65
0
              per_table_values_[it->second][name] = value;
66
0
            }
67
0
            break;
68
0
          default:
69
0
            InvalidAggregationFunction(aggregation_function);
70
0
            break;
71
18.6k
        }
72
18.6k
      }
73
18.6k
    } else {
74
      // For non-tablet level metrics, export them directly.
75
18.6k
      RETURN_NOT_OK(FlushSingleEntry(attr, name, value));
76
18.6k
    }
77
36.7k
    return Status::OK();
78
36.7k
  }
_ZN2yb16PrometheusWriter16WriteSingleEntryIjEENS_6StatusERKNSt3__113unordered_mapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS3_4hashISA_EENS3_8equal_toISA_EENS8_INS3_4pairIKSA_SA_EEEEEERSG_RKT_NS_19AggregationFunctionE
Line
Count
Source
48
55
      AggregationFunction aggregation_function) {
49
55
    auto it = attr.find("table_id");
50
55
    if (it != attr.end()) {
51
      // For tablet level metrics, we roll up on the table level.
52
25
      if (per_table_attributes_.find(it->second) == per_table_attributes_.end()) {
53
        // If it's the first time we see this table, create the aggregate structures.
54
0
        per_table_attributes_[it->second] = attr;
55
0
        per_table_values_[it->second][name] = value;
56
25
      } else {
57
25
        switch (aggregation_function) {
58
25
          case kSum:
59
25
            per_table_values_[it->second][name] += value;
60
25
            break;
61
0
          case kMax:
62
            // If we have a new max, also update the metadata so that it matches correctly.
63
0
            if (static_cast<double>(value) > per_table_values_[it->second][name]) {
64
0
              per_table_attributes_[it->second] = attr;
65
0
              per_table_values_[it->second][name] = value;
66
0
            }
67
0
            break;
68
0
          default:
69
0
            InvalidAggregationFunction(aggregation_function);
70
0
            break;
71
30
        }
72
30
      }
73
30
    } else {
74
      // For non-tablet level metrics, export them directly.
75
30
      RETURN_NOT_OK(FlushSingleEntry(attr, name, value));
76
30
    }
77
55
    return Status::OK();
78
55
  }
_ZN2yb16PrometheusWriter16WriteSingleEntryIxEENS_6StatusERKNSt3__113unordered_mapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS3_4hashISA_EENS3_8equal_toISA_EENS8_INS3_4pairIKSA_SA_EEEEEERSG_RKT_NS_19AggregationFunctionE
Line
Count
Source
48
16.6k
      AggregationFunction aggregation_function) {
49
16.6k
    auto it = attr.find("table_id");
50
16.6k
    if (it != attr.end()) {
51
      // For tablet level metrics, we roll up on the table level.
52
5.24k
      if (per_table_attributes_.find(it->second) == per_table_attributes_.end()) {
53
        // If it's the first time we see this table, create the aggregate structures.
54
6
        per_table_attributes_[it->second] = attr;
55
6
        per_table_values_[it->second][name] = value;
56
5.23k
      } else {
57
5.23k
        switch (aggregation_function) {
58
5.06k
          case kSum:
59
5.06k
            per_table_values_[it->second][name] += value;
60
5.06k
            break;
61
169
          case kMax:
62
            // If we have a new max, also update the metadata so that it matches correctly.
63
169
            if (static_cast<double>(value) > per_table_values_[it->second][name]) {
64
26
              per_table_attributes_[it->second] = attr;
65
26
              per_table_values_[it->second][name] = value;
66
26
            }
67
169
            break;
68
0
          default:
69
0
            InvalidAggregationFunction(aggregation_function);
70
0
            break;
71
11.4k
        }
72
11.4k
      }
73
11.4k
    } else {
74
      // For non-tablet level metrics, export them directly.
75
11.4k
      RETURN_NOT_OK(FlushSingleEntry(attr, name, value));
76
11.4k
    }
77
16.6k
    return Status::OK();
78
16.6k
  }
_ZN2yb16PrometheusWriter16WriteSingleEntryIiEENS_6StatusERKNSt3__113unordered_mapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS3_4hashISA_EENS3_8equal_toISA_EENS8_INS3_4pairIKSA_SA_EEEEEERSG_RKT_NS_19AggregationFunctionE
Line
Count
Source
48
8
      AggregationFunction aggregation_function) {
49
8
    auto it = attr.find("table_id");
50
8
    if (it != attr.end()) {
51
      // For tablet level metrics, we roll up on the table level.
52
8
      if (per_table_attributes_.find(it->second) == per_table_attributes_.end()) {
53
        // If it's the first time we see this table, create the aggregate structures.
54
2
        per_table_attributes_[it->second] = attr;
55
2
        per_table_values_[it->second][name] = value;
56
6
      } else {
57
6
        switch (aggregation_function) {
58
3
          case kSum:
59
3
            per_table_values_[it->second][name] += value;
60
3
            break;
61
3
          case kMax:
62
            // If we have a new max, also update the metadata so that it matches correctly.
63
3
            if (static_cast<double>(value) > per_table_values_[it->second][name]) {
64
3
              per_table_attributes_[it->second] = attr;
65
3
              per_table_values_[it->second][name] = value;
66
3
            }
67
3
            break;
68
0
          default:
69
0
            InvalidAggregationFunction(aggregation_function);
70
0
            break;
71
0
        }
72
0
      }
73
0
    } else {
74
      // For non-tablet level metrics, export them directly.
75
0
      RETURN_NOT_OK(FlushSingleEntry(attr, name, value));
76
0
    }
77
8
    return Status::OK();
78
8
  }
Unexecuted instantiation: _ZN2yb16PrometheusWriter16WriteSingleEntryINSt3__16atomicIyEEEENS_6StatusERKNS2_13unordered_mapINS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEESC_NS2_4hashISC_EENS2_8equal_toISC_EENSA_INS2_4pairIKSC_SC_EEEEEERSI_RKT_NS_19AggregationFunctionE
_ZN2yb16PrometheusWriter16WriteSingleEntryIdEENS_6StatusERKNSt3__113unordered_mapINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_NS3_4hashISA_EENS3_8equal_toISA_EENS8_INS3_4pairIKSA_SA_EEEEEERSG_RKT_NS_19AggregationFunctionE
Line
Count
Source
48
2.75k
      AggregationFunction aggregation_function) {
49
2.75k
    auto it = attr.find("table_id");
50
2.75k
    if (it != attr.end()) {
51
      // For tablet level metrics, we roll up on the table level.
52
0
      if (per_table_attributes_.find(it->second) == per_table_attributes_.end()) {
53
        // If it's the first time we see this table, create the aggregate structures.
54
0
        per_table_attributes_[it->second] = attr;
55
0
        per_table_values_[it->second][name] = value;
56
0
      } else {
57
0
        switch (aggregation_function) {
58
0
          case kSum:
59
0
            per_table_values_[it->second][name] += value;
60
0
            break;
61
0
          case kMax:
62
            // If we have a new max, also update the metadata so that it matches correctly.
63
0
            if (static_cast<double>(value) > per_table_values_[it->second][name]) {
64
0
              per_table_attributes_[it->second] = attr;
65
0
              per_table_values_[it->second][name] = value;
66
0
            }
67
0
            break;
68
0
          default:
69
0
            InvalidAggregationFunction(aggregation_function);
70
0
            break;
71
2.75k
        }
72
2.75k
      }
73
2.75k
    } else {
74
      // For non-tablet level metrics, export them directly.
75
2.75k
      RETURN_NOT_OK(FlushSingleEntry(attr, name, value));
76
2.75k
    }
77
2.75k
    return Status::OK();
78
2.75k
  }
79
80
  CHECKED_STATUS FlushAggregatedValues(const uint32_t& max_tables_metrics_breakdowns,
81
                                       std::string priority_regex);
82
83
 private:
84
  friend class MetricsTest;
85
  // FlushSingleEntry() was a function template with type of "value" as template
86
  // var T. To allow NMSWriter to override FlushSingleEntry(), the type of "value"
87
  // has been instantiated to int64_t.
88
  virtual CHECKED_STATUS FlushSingleEntry(const MetricEntity::AttributeMap& attr,
89
                                          const std::string& name, const int64_t& value);
90
91
  void InvalidAggregationFunction(AggregationFunction aggregation_function);
92
93
  // Map from table_id to attributes
94
  std::map<std::string, MetricEntity::AttributeMap> per_table_attributes_;
95
  // Map from table_id to map of metric_name to value
96
  std::map<std::string, std::map<std::string, double>> per_table_values_;
97
  // Output stream
98
  std::stringstream* output_;
99
  // Timestamp for all metrics belonging to this writer instance.
100
  int64_t timestamp_;
101
};
102
103
// Native Metrics Storage Writer - writes prometheus metrics into system table.
104
class NMSWriter : public PrometheusWriter {
105
 public:
106
  typedef std::unordered_map<std::string, int64_t> MetricsMap;
107
  typedef std::unordered_map<std::string, MetricsMap> EntityMetricsMap;
108
109
  explicit NMSWriter(EntityMetricsMap* table_metrics, MetricsMap* server_metrics);
110
111
 private:
112
  CHECKED_STATUS FlushSingleEntry(
113
      const MetricEntity::AttributeMap& attr, const std::string& name,
114
      const int64_t& value) override;
115
116
  // Output
117
  // Map from table_id to map of metric_name to value
118
  EntityMetricsMap* table_metrics_;
119
  // Map from metric_name to value
120
  MetricsMap* server_metrics_;
121
};
122
123
} // namespace yb
124
125
#endif // YB_UTIL_METRICS_WRITER_H