Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/source/common/stats/metric_impl.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/common/stats/metric_impl.h"
2
3
#include "envoy/stats/tag.h"
4
5
#include "source/common/stats/symbol_table.h"
6
7
namespace Envoy {
8
namespace Stats {
9
10
52.9M
MetricHelper::~MetricHelper() {
11
  // The storage must be cleaned by a subclass of MetricHelper in its
12
  // destructor, because the symbol-table is owned by the subclass.
13
  // Simply call MetricHelper::clear() in the subclass dtor.
14
52.9M
  ASSERT(!stat_names_.populated());
15
52.9M
}
16
17
MetricHelper::MetricHelper(StatName name, StatName tag_extracted_name,
18
52.9M
                           const StatNameTagVector& stat_name_tags, SymbolTable& symbol_table) {
19
  // Encode all the names and tags into transient storage so we can count the
20
  // required bytes. 2 is added to account for the name and tag_extracted_name,
21
  // and we multiply the number of tags by 2 to account for the name and value
22
  // of each tag.
23
52.9M
  const uint32_t num_names = 2 + 2 * stat_name_tags.size();
24
52.9M
  absl::FixedArray<StatName> names(num_names);
25
52.9M
  names[0] = name;
26
52.9M
  names[1] = tag_extracted_name;
27
52.9M
  int index = 1;
28
52.9M
  for (auto& stat_name_tag : stat_name_tags) {
29
715k
    names[++index] = stat_name_tag.first;
30
715k
    names[++index] = stat_name_tag.second;
31
715k
  }
32
52.9M
  symbol_table.populateList(names.begin(), num_names, stat_names_);
33
52.9M
}
34
35
394M
StatName MetricHelper::statName() const {
36
394M
  StatName stat_name;
37
394M
  stat_names_.iterate([&stat_name](StatName s) -> bool {
38
394M
    stat_name = s;
39
394M
    return false; // Returning 'false' stops the iteration.
40
394M
  });
41
394M
  return stat_name;
42
394M
}
43
44
0
StatName MetricHelper::tagExtractedStatName() const {
45
  // The name is the first element in stat_names_. The second is the
46
  // tag-extracted-name. We don't have random access in that format,
47
  // so we iterate through them, skipping the first element (name),
48
  // and terminating the iteration after capturing the tag-extracted
49
  // name by returning false from the lambda.
50
0
  StatName tag_extracted_stat_name;
51
0
  bool skip = true;
52
0
  stat_names_.iterate([&tag_extracted_stat_name, &skip](StatName s) -> bool {
53
0
    if (skip) {
54
0
      skip = false;
55
0
      return true;
56
0
    }
57
0
    tag_extracted_stat_name = s;
58
0
    return false; // Returning 'false' stops the iteration.
59
0
  });
60
0
  return tag_extracted_stat_name;
61
0
}
62
63
0
void MetricHelper::iterateTagStatNames(const Metric::TagStatNameIterFn& fn) const {
64
0
  enum { Name, TagExtractedName, TagName, TagValue } state = Name;
65
0
  StatName tag_name;
66
67
  // StatNameList maintains a linear ordered collection of StatNames, and we
68
  // are mapping that into a tag-extracted name (the first element), followed
69
  // by alternating TagName and TagValue. So we use a little state machine
70
  // as we iterate through the stat_names_.
71
0
  stat_names_.iterate([&state, &tag_name, &fn](StatName stat_name) -> bool {
72
0
    switch (state) {
73
0
    case Name:
74
0
      state = TagExtractedName;
75
0
      break;
76
0
    case TagExtractedName:
77
0
      state = TagName;
78
0
      break;
79
0
    case TagName:
80
0
      tag_name = stat_name;
81
0
      state = TagValue;
82
0
      break;
83
0
    case TagValue:
84
0
      state = TagName;
85
0
      if (!fn(tag_name, stat_name)) {
86
0
        return false; // early exit.
87
0
      }
88
0
      break;
89
0
    }
90
0
    return true;
91
0
  });
92
0
  ASSERT(state != TagValue);
93
0
}
94
95
0
TagVector MetricHelper::tags(const SymbolTable& symbol_table) const {
96
0
  TagVector tags;
97
0
  iterateTagStatNames([&tags, &symbol_table](StatName name, StatName value) -> bool {
98
0
    tags.emplace_back(Tag{symbol_table.toString(name), symbol_table.toString(value)});
99
0
    return true;
100
0
  });
101
0
  return tags;
102
0
}
103
104
} // namespace Stats
105
} // namespace Envoy