1
#include "source/common/stats/utility.h"
2

            
3
#include <algorithm>
4
#include <string>
5

            
6
#include "absl/strings/match.h"
7
#include "absl/strings/str_replace.h"
8
#include "absl/types/optional.h"
9

            
10
namespace Envoy {
11
namespace Stats {
12

            
13
487363
std::string Utility::sanitizeStatsName(absl::string_view name) {
14
487363
  if (absl::EndsWith(name, ".")) {
15
180466
    name.remove_suffix(1);
16
180466
  }
17
487363
  if (absl::StartsWith(name, ".")) {
18
2
    name.remove_prefix(1);
19
2
  }
20

            
21
487363
  return absl::StrReplaceAll(name, {
22
487363
                                       {"://", "_"},
23
487363
                                       {":/", "_"},
24
487363
                                       {":", "_"},
25
487363
                                       {absl::string_view("\0", 1), "_"},
26
487363
                                   });
27
487363
}
28

            
29
4
absl::optional<StatName> Utility::findTag(const Metric& metric, StatName find_tag_name) {
30
4
  absl::optional<StatName> value;
31
4
  metric.iterateTagStatNames(
32
6
      [&value, &find_tag_name](Stats::StatName tag_name, Stats::StatName tag_value) -> bool {
33
6
        if (tag_name == find_tag_name) {
34
3
          value = tag_value;
35
3
          return false;
36
3
        }
37
3
        return true;
38
6
      });
39
4
  return value;
40
4
}
41

            
42
namespace {
43

            
44
// Helper class for the three Utility::*FromElements implementations to build up
45
// a joined StatName from a mix of StatName and string_view.
46
struct ElementVisitor {
47
  ElementVisitor(SymbolTable& symbol_table, const ElementVec& elements)
48
2484371
      : symbol_table_(symbol_table), pool_(symbol_table) {
49
2484371
    stat_names_.resize(elements.size());
50
7422084
    for (const Element& element : elements) {
51
7422084
      absl::visit(*this, element);
52
7422084
    }
53
2484371
    joined_ = symbol_table_.join(stat_names_);
54
2484371
  }
55

            
56
  // Overloads provides for absl::visit to call.
57
7410410
  void operator()(StatName stat_name) { stat_names_.push_back(stat_name); }
58
11675
  void operator()(absl::string_view name) { stat_names_.push_back(pool_.add(name)); }
59

            
60
  /**
61
   * @return the StatName constructed by joining the elements.
62
   */
63
2484371
  StatName statName() { return StatName(joined_.get()); }
64

            
65
  SymbolTable& symbol_table_;
66
  StatNameVec stat_names_;
67
  StatNameDynamicPool pool_;
68
  SymbolTable::StoragePtr joined_;
69
};
70

            
71
} // namespace
72

            
73
namespace Utility {
74

            
75
90
ScopeSharedPtr scopeFromStatNames(Scope& scope, const StatNameVec& elements) {
76
90
  SymbolTable::StoragePtr joined = scope.symbolTable().join(elements);
77
90
  return scope.scopeFromStatName(StatName(joined.get()));
78
90
}
79

            
80
Counter& counterFromElements(Scope& scope, const ElementVec& elements,
81
7982
                             StatNameTagVectorOptConstRef tags) {
82
7982
  ElementVisitor visitor(scope.symbolTable(), elements);
83
7982
  return scope.counterFromStatNameWithTags(visitor.statName(), tags);
84
7982
}
85

            
86
Counter& counterFromStatNames(Scope& scope, const StatNameVec& elements,
87
19595291
                              StatNameTagVectorOptConstRef tags) {
88
19595291
  SymbolTable::StoragePtr joined = scope.symbolTable().join(elements);
89
19595291
  return scope.counterFromStatNameWithTags(StatName(joined.get()), tags);
90
19595291
}
91

            
92
Gauge& gaugeFromElements(Scope& scope, const ElementVec& elements, Gauge::ImportMode import_mode,
93
2476235
                         StatNameTagVectorOptConstRef tags) {
94
2476235
  ElementVisitor visitor(scope.symbolTable(), elements);
95
2476235
  return scope.gaugeFromStatNameWithTags(visitor.statName(), tags, import_mode);
96
2476235
}
97

            
98
Gauge& gaugeFromStatNames(Scope& scope, const StatNameVec& elements, Gauge::ImportMode import_mode,
99
3204984
                          StatNameTagVectorOptConstRef tags) {
100
3204984
  SymbolTable::StoragePtr joined = scope.symbolTable().join(elements);
101
3204984
  return scope.gaugeFromStatNameWithTags(StatName(joined.get()), tags, import_mode);
102
3204984
}
103

            
104
Histogram& histogramFromElements(Scope& scope, const ElementVec& elements, Histogram::Unit unit,
105
108
                                 StatNameTagVectorOptConstRef tags) {
106
108
  ElementVisitor visitor(scope.symbolTable(), elements);
107
108
  return scope.histogramFromStatNameWithTags(visitor.statName(), tags, unit);
108
108
}
109

            
110
Histogram& histogramFromStatNames(Scope& scope, const StatNameVec& elements, Histogram::Unit unit,
111
2565830
                                  StatNameTagVectorOptConstRef tags) {
112
2565830
  SymbolTable::StoragePtr joined = scope.symbolTable().join(elements);
113
2565830
  return scope.histogramFromStatNameWithTags(StatName(joined.get()), tags, unit);
114
2565830
}
115

            
116
TextReadout& textReadoutFromElements(Scope& scope, const ElementVec& elements,
117
46
                                     StatNameTagVectorOptConstRef tags) {
118
46
  ElementVisitor visitor(scope.symbolTable(), elements);
119
46
  return scope.textReadoutFromStatNameWithTags(visitor.statName(), tags);
120
46
}
121

            
122
TextReadout& textReadoutFromStatNames(Scope& scope, const StatNameVec& elements,
123
4
                                      StatNameTagVectorOptConstRef tags) {
124
4
  SymbolTable::StoragePtr joined = scope.symbolTable().join(elements);
125
4
  return scope.textReadoutFromStatNameWithTags(StatName(joined.get()), tags);
126
4
}
127

            
128
} // namespace Utility
129
} // namespace Stats
130
} // namespace Envoy