Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/source/common/stats/metric_impl.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <string>
4
#include <vector>
5
6
#include "envoy/stats/allocator.h"
7
#include "envoy/stats/stats.h"
8
#include "envoy/stats/tag.h"
9
10
#include "source/common/common/assert.h"
11
#include "source/common/stats/symbol_table.h"
12
13
namespace Envoy {
14
namespace Stats {
15
16
/**
17
 * Helper class for implementing Metrics. This does not participate in any
18
 * inheritance chains, but can be instantiated by classes that do. It just
19
 * implements the mechanics of representing the name, tag-extracted-name,
20
 * and all tags as a StatNameList.
21
 */
22
class MetricHelper {
23
public:
24
  MetricHelper(StatName name, StatName tag_extracted_name, const StatNameTagVector& stat_name_tags,
25
               SymbolTable& symbol_table);
26
  ~MetricHelper();
27
28
  StatName statName() const;
29
  std::string name(const SymbolTable& symbol_table) const;
30
  TagVector tags(const SymbolTable& symbol_table) const;
31
  StatName tagExtractedStatName() const;
32
  void iterateTagStatNames(const Metric::TagStatNameIterFn& fn) const;
33
52.9M
  void clear(SymbolTable& symbol_table) { stat_names_.clear(symbol_table); }
34
35
  // Hasher for metrics.
36
  struct Hash {
37
    using is_transparent = void; // NOLINT(readability-identifier-naming)
38
146M
    size_t operator()(const Metric* a) const { return a->statName().hash(); }
39
177M
    size_t operator()(StatName a) const { return a.hash(); }
40
  };
41
42
  // Comparator for metrics.
43
  struct Compare {
44
    using is_transparent = void; // NOLINT(readability-identifier-naming)
45
50.6M
    bool operator()(const Metric* a, const Metric* b) const {
46
50.6M
      return a->statName() == b->statName();
47
50.6M
    }
48
51.6M
    bool operator()(const Metric* a, StatName b) const { return a->statName() == b; }
49
  };
50
51
private:
52
  StatNameList stat_names_;
53
};
54
55
// An unordered set of stat pointers. which keys off Metric::statName().
56
// This necessitates a custom comparator and hasher, using the StatNamePtr's
57
// own StatNamePtrHash and StatNamePtrCompare operators.
58
//
59
// This is used by AllocatorImpl for counters, gauges, and text-readouts, and
60
// is also used by thread_local_store.h for histograms.
61
template <class StatType>
62
using StatSet = absl::flat_hash_set<StatType*, MetricHelper::Hash, MetricHelper::Compare>;
63
64
/**
65
 * Partial implementation of the Metric interface on behalf of Counters, Gauges,
66
 * and Histograms. It leaves symbolTable() unimplemented so that implementations
67
 * of stats managed by an allocator, specifically Counters and Gauges, can keep
68
 * a reference to the allocator instead, and derive the symbolTable() from that.
69
 *
70
 * We templatize on the base class (Counter, Gauge, or Histogram), rather than
71
 * using multiple virtual inheritance, as this avoids the overhead of an extra
72
 * vptr per instance. This is important for stats because there can be many
73
 * stats in systems with large numbers of clusters and hosts, and a few 8-byte
74
 * pointers per-stat here and there can add up to significant amounts of memory.
75
 *
76
 * Note the delegation of the implementation to a helper class, which is neither
77
 * templatized nor virtual. This avoids having the compiler elaborate complete
78
 * copies of the underlying implementation for each base class during template
79
 * expansion.
80
 */
81
template <class BaseClass> class MetricImpl : public BaseClass {
82
public:
83
  MetricImpl(StatName name, StatName tag_extracted_name, const StatNameTagVector& stat_name_tags,
84
             SymbolTable& symbol_table)
85
52.9M
      : helper_(name, tag_extracted_name, stat_name_tags, symbol_table) {}
Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::MetricImpl(Envoy::Stats::StatName, Envoy::Stats::StatName, std::__1::vector<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName>, std::__1::allocator<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName> > > const&, Envoy::Stats::SymbolTable&)
Line
Count
Source
85
37.0M
      : helper_(name, tag_extracted_name, stat_name_tags, symbol_table) {}
Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::MetricImpl(Envoy::Stats::StatName, Envoy::Stats::StatName, std::__1::vector<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName>, std::__1::allocator<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName> > > const&, Envoy::Stats::SymbolTable&)
Line
Count
Source
85
12.6M
      : helper_(name, tag_extracted_name, stat_name_tags, symbol_table) {}
Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::MetricImpl(Envoy::Stats::StatName, Envoy::Stats::StatName, std::__1::vector<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName>, std::__1::allocator<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName> > > const&, Envoy::Stats::SymbolTable&)
Line
Count
Source
85
3.24M
      : helper_(name, tag_extracted_name, stat_name_tags, symbol_table) {}
Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::MetricImpl(Envoy::Stats::StatName, Envoy::Stats::StatName, std::__1::vector<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName>, std::__1::allocator<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName> > > const&, Envoy::Stats::SymbolTable&)
Line
Count
Source
85
5.74k
      : helper_(name, tag_extracted_name, stat_name_tags, symbol_table) {}
Envoy::Stats::MetricImpl<Envoy::Stats::ParentHistogram>::MetricImpl(Envoy::Stats::StatName, Envoy::Stats::StatName, std::__1::vector<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName>, std::__1::allocator<std::__1::pair<Envoy::Stats::StatName, Envoy::Stats::StatName> > > const&, Envoy::Stats::SymbolTable&)
Line
Count
Source
85
27.8k
      : helper_(name, tag_extracted_name, stat_name_tags, symbol_table) {}
86
87
  // Empty construction of a MetricImpl; used for null stats.
88
  explicit MetricImpl(SymbolTable& symbol_table)
89
5.41M
      : MetricImpl(StatName(), StatName(), StatNameTagVector(), symbol_table) {}
Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::MetricImpl(Envoy::Stats::SymbolTable&)
Line
Count
Source
89
2.70M
      : MetricImpl(StatName(), StatName(), StatNameTagVector(), symbol_table) {}
Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::MetricImpl(Envoy::Stats::SymbolTable&)
Line
Count
Source
89
2.70M
      : MetricImpl(StatName(), StatName(), StatNameTagVector(), symbol_table) {}
Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::MetricImpl(Envoy::Stats::SymbolTable&)
Line
Count
Source
89
1.97k
      : MetricImpl(StatName(), StatName(), StatNameTagVector(), symbol_table) {}
Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::MetricImpl(Envoy::Stats::SymbolTable&)
Line
Count
Source
89
1.97k
      : MetricImpl(StatName(), StatName(), StatNameTagVector(), symbol_table) {}
90
91
0
  TagVector tags() const override { return helper_.tags(constSymbolTable()); }
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::tags() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::tags() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::tags() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::tags() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::ParentHistogram>::tags() const
92
394M
  StatName statName() const override { return helper_.statName(); }
Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::statName() const
Line
Count
Source
92
304M
  StatName statName() const override { return helper_.statName(); }
Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::statName() const
Line
Count
Source
92
87.0M
  StatName statName() const override { return helper_.statName(); }
Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::statName() const
Line
Count
Source
92
3.23M
  StatName statName() const override { return helper_.statName(); }
Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::statName() const
Line
Count
Source
92
34.9k
  StatName statName() const override { return helper_.statName(); }
Envoy::Stats::MetricImpl<Envoy::Stats::ParentHistogram>::statName() const
Line
Count
Source
92
215k
  StatName statName() const override { return helper_.statName(); }
93
0
  StatName tagExtractedStatName() const override { return helper_.tagExtractedStatName(); }
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::tagExtractedStatName() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::tagExtractedStatName() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::tagExtractedStatName() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::tagExtractedStatName() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::ParentHistogram>::tagExtractedStatName() const
94
0
  void iterateTagStatNames(const Metric::TagStatNameIterFn& fn) const override {
95
0
    helper_.iterateTagStatNames(fn);
96
0
  }
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::iterateTagStatNames(std::__1::function<bool (Envoy::Stats::StatName, Envoy::Stats::StatName)> const&) const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::iterateTagStatNames(std::__1::function<bool (Envoy::Stats::StatName, Envoy::Stats::StatName)> const&) const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::iterateTagStatNames(std::__1::function<bool (Envoy::Stats::StatName, Envoy::Stats::StatName)> const&) const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::iterateTagStatNames(std::__1::function<bool (Envoy::Stats::StatName, Envoy::Stats::StatName)> const&) const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::ParentHistogram>::iterateTagStatNames(std::__1::function<bool (Envoy::Stats::StatName, Envoy::Stats::StatName)> const&) const
97
98
2.71M
  const SymbolTable& constSymbolTable() const override {
99
    // Cast our 'this', which is of type `const MetricImpl*` to a non-const
100
    // pointer, so we can use it to call the subclass implementation of
101
    // symbolTable(). That will be returned as a non-const SymbolTable&,
102
    // which will become const on return.
103
    //
104
    // This pattern is used to share a single non-trivial implementation to
105
    // provide const and non-const variants of a method.
106
2.71M
    return const_cast<MetricImpl*>(this)->symbolTable();
107
2.71M
  }
Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::constSymbolTable() const
Line
Count
Source
98
2.64M
  const SymbolTable& constSymbolTable() const override {
99
    // Cast our 'this', which is of type `const MetricImpl*` to a non-const
100
    // pointer, so we can use it to call the subclass implementation of
101
    // symbolTable(). That will be returned as a non-const SymbolTable&,
102
    // which will become const on return.
103
    //
104
    // This pattern is used to share a single non-trivial implementation to
105
    // provide const and non-const variants of a method.
106
2.64M
    return const_cast<MetricImpl*>(this)->symbolTable();
107
2.64M
  }
Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::constSymbolTable() const
Line
Count
Source
98
73.1k
  const SymbolTable& constSymbolTable() const override {
99
    // Cast our 'this', which is of type `const MetricImpl*` to a non-const
100
    // pointer, so we can use it to call the subclass implementation of
101
    // symbolTable(). That will be returned as a non-const SymbolTable&,
102
    // which will become const on return.
103
    //
104
    // This pattern is used to share a single non-trivial implementation to
105
    // provide const and non-const variants of a method.
106
73.1k
    return const_cast<MetricImpl*>(this)->symbolTable();
107
73.1k
  }
Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::constSymbolTable() const
Line
Count
Source
98
2
  const SymbolTable& constSymbolTable() const override {
99
    // Cast our 'this', which is of type `const MetricImpl*` to a non-const
100
    // pointer, so we can use it to call the subclass implementation of
101
    // symbolTable(). That will be returned as a non-const SymbolTable&,
102
    // which will become const on return.
103
    //
104
    // This pattern is used to share a single non-trivial implementation to
105
    // provide const and non-const variants of a method.
106
2
    return const_cast<MetricImpl*>(this)->symbolTable();
107
2
  }
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::constSymbolTable() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::ParentHistogram>::constSymbolTable() const
108
2.71M
  std::string name() const override { return constSymbolTable().toString(this->statName()); }
Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::name() const
Line
Count
Source
108
2.64M
  std::string name() const override { return constSymbolTable().toString(this->statName()); }
Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::name() const
Line
Count
Source
108
73.1k
  std::string name() const override { return constSymbolTable().toString(this->statName()); }
Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::name() const
Line
Count
Source
108
2
  std::string name() const override { return constSymbolTable().toString(this->statName()); }
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::name() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::ParentHistogram>::name() const
109
0
  std::string tagExtractedName() const override {
110
0
    return constSymbolTable().toString(this->tagExtractedStatName());
111
0
  }
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::tagExtractedName() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::tagExtractedName() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::tagExtractedName() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::tagExtractedName() const
Unexecuted instantiation: Envoy::Stats::MetricImpl<Envoy::Stats::ParentHistogram>::tagExtractedName() const
112
113
protected:
114
52.9M
  void clear(SymbolTable& symbol_table) { helper_.clear(symbol_table); }
Envoy::Stats::MetricImpl<Envoy::Stats::Counter>::clear(Envoy::Stats::SymbolTable&)
Line
Count
Source
114
37.0M
  void clear(SymbolTable& symbol_table) { helper_.clear(symbol_table); }
Envoy::Stats::MetricImpl<Envoy::Stats::Gauge>::clear(Envoy::Stats::SymbolTable&)
Line
Count
Source
114
12.6M
  void clear(SymbolTable& symbol_table) { helper_.clear(symbol_table); }
Envoy::Stats::MetricImpl<Envoy::Stats::Histogram>::clear(Envoy::Stats::SymbolTable&)
Line
Count
Source
114
3.24M
  void clear(SymbolTable& symbol_table) { helper_.clear(symbol_table); }
Envoy::Stats::MetricImpl<Envoy::Stats::TextReadout>::clear(Envoy::Stats::SymbolTable&)
Line
Count
Source
114
5.74k
  void clear(SymbolTable& symbol_table) { helper_.clear(symbol_table); }
Envoy::Stats::MetricImpl<Envoy::Stats::ParentHistogram>::clear(Envoy::Stats::SymbolTable&)
Line
Count
Source
114
27.8k
  void clear(SymbolTable& symbol_table) { helper_.clear(symbol_table); }
115
116
private:
117
  MetricHelper helper_;
118
};
119
120
} // namespace Stats
121
} // namespace Envoy