Skip to content

Commit 03b2e9d

Browse files
authored
Introduce tag numbering (#112)
* Introduce tag numbering * Adapt docs * Adapt metric tests * Add freely global tags
1 parent dee48df commit 03b2e9d

File tree

16 files changed

+126
-78
lines changed

16 files changed

+126
-78
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ A metric consist of 5 parameters: name, value, timestamp, verbosity and tags.
9191
| verbosity | DEBUG / INFO / PROD | no | INFO |
9292
| tags | vector<unsigned int> | no | - |
9393

94-
A metric can be constructed by providing required parameters:
94+
A metric can be constructed by providing required parameters (value and name):
9595
```cpp
9696
Metric{10, "name"}
9797
```
@@ -108,7 +108,7 @@ Metrics need to match backends verbosity in order to be sent, eg. backend with `
108108

109109
#### Tags
110110
Each metric can be tagged with any number of [predefined tags](include/Monitoring/Tags.h).
111-
In order to do so use `addTags(std::initializer_list<unsigned int>&& tags)` method.
111+
In order to do so use `addTag(tags::Key, tags::Value)` or `addTag(tags::Key, unsigned short)` methods. The latter method allows assigning numeric value to a tag.
112112

113113
See the example: [examples/2-TaggedMetrics.cxx](examples/2-TaggedMetrics.cxx).
114114

@@ -165,7 +165,7 @@ Glabal tags are tags that are added to each metric. The following tags are set t
165165
- `hostname`
166166
- `name` - process name
167167

168-
You can add your own global tag by calling `addGlobalTag(std::string name, std::string value)`.
168+
You can add your own global tag by calling `addGlobalTag(std::string_view key, std::string_view value)` or `addGlobalTag(tags::Key, tags::Value)`.
169169

170170
### Process monitoring
171171
```cpp

examples/2-TaggedMetrics.cxx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ int main() {
1414
auto monitoring = MonitoringFactory::Get("stdout://");
1515

1616
/// Add global tags
17-
monitoring->addGlobalTag("example", "yes");
18-
monitoring->addGlobalTag(tags::Subsystem::DPL);
17+
monitoring->addGlobalTag("name", "test");
18+
monitoring->addGlobalTag(tags::Key::Subsystem, tags::Value::DPL);
1919

2020
// now send an application specific metric with additional tags
2121
// 10 is the value
2222
// myMetric is the name of the metric
2323
// then add predefined tag
24-
monitoring->send(Metric{10, "myMetric"}.addTags({tags::Detector::TPC}));
24+
monitoring->send(Metric{10, "myMetric"}.addTag(tags::Key::Detector, tags::Value::TPC));
25+
monitoring->send(Metric{10, "myMetric"}.addTag(tags::Key::CRU, 123));
2526
}

examples/4-RateDerivedMetric.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ int main() {
1414

1515
// now send at least two metrics to see the result
1616
for (int i = 0; i < 101; i += 10) {
17-
monitoring->send(Metric{i, "myMetric"}.addTags({tags::Subsystem::Readout}), DerivedMetricMode::RATE);
17+
monitoring->send(Metric{i, "myMetric"}.addTag(tags::Key::Subsystem, tags::Value::Readout), DerivedMetricMode::RATE);
1818
std::this_thread::sleep_for(std::chrono::milliseconds(100));
1919
}
2020
}

examples/7-InternalBenchamrk.cxx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ void test(std::unique_ptr<Monitoring>& monitoring) {
1717
}
1818

1919
void testWithTags(std::unique_ptr<Monitoring>& monitoring) {
20-
monitoring->addGlobalTag("benchmark", "yes");
20+
monitoring->addGlobalTag("name", "benchmark");
2121
for (int i = 0; i < 100000; i++) {
22-
monitoring->send(Metric{10, "myMetricInt"}.addTags({tags::Detector::TPC}));
23-
monitoring->send(Metric{10.10, "myMetricFloat"}.addTags({tags::Subsystem::QC}));
22+
monitoring->send(Metric{10, "myMetricInt"}.addTag(tags::Key::Detector, tags::Value::TPC));
23+
monitoring->send(Metric{10.10, "myMetricFloat"}.addTag(tags::Key::Subsystem, tags::Value::QC));
2424
}
2525
}
2626

include/Monitoring/Metric.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@ namespace o2
1818
namespace monitoring
1919
{
2020

21+
/// Metric and Backedn verbosity
2122
enum class Verbosity : short { PROD, INFO, DEBUG };
2223

24+
25+
/// Metric types
2326
enum MetricType { INT = 0, STRING = 1, DOUBLE = 2, UINT64_T = 3 };
2427

28+
class DerivedMetrics;
29+
2530
/// \brief Represents a metric including value, type of the value, name, timestamp and tags
2631
class Metric
2732
{
@@ -72,12 +77,19 @@ class Metric
7277

7378
/// Tag list getter
7479
/// \return tags
75-
const std::vector<unsigned int>& getTags() const;
80+
const std::vector<std::pair<int, int>>& getTags() const;
81+
82+
/// Add user defined tags
83+
/// \param key enum tag key
84+
/// \param value emum tag value
85+
/// \return r-value to "this" - to be able to chain methods
86+
Metric&& addTag(tags::Key key, tags::Value value);
7687

7788
/// Add user defined tags
78-
/// \param tags r-value to vector of tags
89+
/// \param key enum tag key
90+
/// \param value numeric value
7991
/// \return r-value to "this" - to be able to chain methods
80-
Metric&& addTags(std::vector<unsigned int>&& tags);
92+
Metric&& addTag(tags::Key key, unsigned short int number);
8193

8294
/// Verbosity getter
8395
Verbosity getVerbosity();
@@ -92,6 +104,12 @@ class Metric
92104
/// Default metric verbosity
93105
static Verbosity DEFAULT_VERBOSITY;
94106
protected:
107+
/// Allow DerivedMetrics access to setTags
108+
friend class o2::monitoring::DerivedMetrics;
109+
110+
/// Set full vector of tags
111+
Metric&& setTags(std::vector<std::pair<int, int>>&& tags);
112+
95113
/// Metric value
96114
boost::variant< int, std::string, double, uint64_t > mValue;
97115

@@ -102,7 +120,7 @@ class Metric
102120
std::chrono::time_point<std::chrono::system_clock> mTimestamp;
103121

104122
/// Metric tags
105-
std::vector<unsigned int> mTags;
123+
std::vector<std::pair<int, int>> mTags;
106124

107125
/// Metric verbosity
108126
Verbosity mVerbosity;

include/Monitoring/Monitoring.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,10 @@ class Monitoring
8181
/// \param value tag value
8282
void addGlobalTag(std::string_view name, std::string_view value);
8383

84-
/// Adds predefined global tag
85-
/// \param tag tag index (use predefined enums form tag:: namespace)
86-
void addGlobalTag(const unsigned int tag);
84+
/// Adds global tag
85+
/// \param name tag name
86+
/// \param value tag value
87+
void addGlobalTag(tags::Key key, tags::Value value);
8788

8889
/// Returns a metric which will be periodically sent to backends
8990
/// \param name metric name

include/Monitoring/Tags.h

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,37 +18,43 @@ namespace tags
1818
{
1919
using namespace std::string_view_literals;
2020

21-
// Detector tag indexes
22-
static constexpr std::string_view detectorTag = "detector";
23-
enum Detector { ACO = 0 , AD, CPV, EMC, FMD, HMP, MCH, MTR, PHS, PMD, ITS, T0, TOF, TPC, TRD, V0};
24-
25-
// Subsystem tag indexes
26-
static constexpr std::string_view subsystemTag = "subsystem";
27-
enum Subsystem { QC = 16, Readout, DPL, CRU };
28-
29-
// Single tag array
30-
static constexpr std::array<std::pair<std::string_view, std::string_view>, 20> TAG_ARRAY = {{
31-
{detectorTag, "ACO"sv}, // 0
32-
{detectorTag, "AD"sv}, // 1
33-
{detectorTag, "CPV"sv}, // 2
34-
{detectorTag, "EMC"sv}, // 3
35-
{detectorTag, "FMD"sv}, // 4
36-
{detectorTag, "HMP"sv}, // 5
37-
{detectorTag, "MCH"sv}, // 6
38-
{detectorTag, "MTR"sv}, // 7
39-
{detectorTag, "PHS"sv}, // 8
40-
{detectorTag, "PHS"sv}, // 9
41-
{detectorTag, "PMD"sv}, // 10
42-
{detectorTag, "ITS"sv}, // 11
43-
{detectorTag, "TOF"sv}, // 12
44-
{detectorTag, "TPC"sv}, // 13
45-
{detectorTag, "TRD"sv}, // 14
46-
{detectorTag, "V0"sv}, // 15
47-
{subsystemTag, "QC"sv},
48-
{subsystemTag, "Readout"sv},
49-
{subsystemTag, "DLP"sv},
50-
{subsystemTag, "CRU"sv}
21+
// Tag keys
22+
enum class Key : unsigned short int { Hostname, Rolename, Name, Detector, Subsystem, CRU, FLP, EPN };
23+
24+
/// Tag keys array
25+
static constexpr std::array<std::string_view, 8> TAG_KEY = {
26+
"hostname"sv, "rolenane"sv, "name"sv, "detector"sv, "subsystem"sv, "CRU"sv, "FLP"sv, "EPN"sv
27+
};
28+
29+
// Tag values
30+
enum class Value : unsigned short int { ACO, AD, CPV, EMC, FMD, HMP, MCH, MTR, PHS, PMD, ITS, T0, TOF, TPC, TRD, V0, QC, Readout, DPL, CRU};
31+
32+
// Tag value array
33+
static constexpr std::array<std::string_view, 20> TAG_VALUE = {{
34+
"ACO"sv,
35+
"AD"sv, // 1
36+
"CPV"sv, // 2
37+
"EMC"sv, // 3
38+
"FMD"sv, // 4
39+
"HMP"sv, // 5
40+
"MCH"sv, // 6
41+
"MTR"sv, // 7
42+
"PHS"sv, // 8
43+
"PHS"sv, // 9
44+
"PMD"sv, // 10
45+
"ITS"sv, // 11
46+
"TOF"sv, // 12
47+
"TPC"sv, // 13
48+
"TRD"sv, // 14
49+
"V0"sv, // 15
50+
"QC"sv,
51+
"Readout"sv,
52+
"DPL"sv,
53+
"CRU"sv
5154
}};
55+
static constexpr std::string_view GetValue(const int value) {
56+
return value >= 0 ? TAG_VALUE[value] : std::to_string(0 - value);
57+
}
5258
}
5359

5460
} // namespace monitoring

src/Backends/Flume.cxx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ std::string Flume::metricToJson(const Metric& metric)
3333
header.put<std::string>("name", metric.getName());
3434
header.put<std::string>("value_value", boost::lexical_cast<std::string>(metric.getValue()));
3535

36-
for (const auto& tagIndex : metric.getTags()) {
37-
header.put<std::string>("tag_" + std::string(tags::TAG_ARRAY[tagIndex].first.data()), tags::TAG_ARRAY[tagIndex].second.data());
36+
for (const auto& [key, value] : metric.getTags()) {
37+
header.put<std::string>("tag_" + std::string(tags::TAG_KEY[key].data()), tags::GetValue(value).data());
3838
}
3939
event.push_back(std::make_pair("headers", header));
4040
event.put<std::string>("body", "");
@@ -67,8 +67,8 @@ std::string Flume::metricsToJson(std::string measurement, std::vector<Metric>&&
6767
boost::property_tree::ptree header = globalHeader;
6868
header.put<std::string>("timestamp", std::to_string(convertTimestamp(metrics.front().getTimestamp())));
6969
header.put<std::string>("name", measurement);
70-
for (const auto& tagIndex : metrics.front().getTags()) {
71-
header.put<std::string>("tag_" + std::string(tags::TAG_ARRAY[tagIndex].first.data()), tags::TAG_ARRAY[tagIndex].second.data());
70+
for (const auto& [key, value] : metrics.front().getTags()) {
71+
header.put<std::string>("tag_" + std::string(tags::TAG_KEY[key].data()), tags::GetValue(value).data());
7272
}
7373
for (auto& metric : metrics) {
7474
header.put<std::string>("value_" + metric.getName(), boost::lexical_cast<std::string>(metric.getValue()));

src/Backends/InfluxDB.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ std::string InfluxDB::toInfluxLineProtocol(const Metric& metric) {
9797
escape(name);
9898
convert << name << "," << tagSet;
9999

100-
for (const auto& tagIndex : metric.getTags()) {
101-
convert << "," << tags::TAG_ARRAY[tagIndex].first << "=" << tags::TAG_ARRAY[tagIndex].second;
100+
for (const auto& [key, value] : metric.getTags()) {
101+
convert << "," << tags::TAG_KEY[key] << "=" << tags::GetValue(value);
102102
}
103103

104104
std::string value = boost::lexical_cast<std::string>(metric.getValue());

src/Backends/StdOut.cxx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ void StdOut::send(std::vector<Metric>&& metrics) {
4747
void StdOut::sendMultiple(std::string measurement, std::vector<Metric>&& metrics)
4848
{
4949
std::string metricTags{};
50-
for (const auto& tagIndex : metrics.front().getTags()) {
50+
for (const auto& [key, value] : metrics.front().getTags()) {
5151
metricTags += ',';
52-
metricTags += tags::TAG_ARRAY[tagIndex].first;
52+
metricTags += tags::TAG_KEY[key];
5353
metricTags += "=";
54-
metricTags += tags::TAG_ARRAY[tagIndex].second;
54+
metricTags += tags::GetValue(value);
5555
}
5656
for (auto& metric : metrics) {
5757
mStream << "[METRIC] " << measurement << '/' << metric.getName() << ',' << metric.getType() << ' '
@@ -65,8 +65,8 @@ void StdOut::send(const Metric& metric)
6565
mStream << "[METRIC] " << metric.getName() << ',' << metric.getType() << " " << metric.getValue()
6666
<< ' ' << convertTimestamp(metric.getTimestamp()) << ' ' << tagString;
6767

68-
for (const auto& tagIndex : metric.getTags()) {
69-
mStream << ',' << tags::TAG_ARRAY[tagIndex].first << "=" << tags::TAG_ARRAY[tagIndex].second;
68+
for (const auto& [key, value] : metric.getTags()) {
69+
mStream << ',' << tags::TAG_KEY[key] << "=" << tags::GetValue(value);
7070
}
7171
mStream << '\n';
7272
}

0 commit comments

Comments
 (0)