Skip to content

Commit 195c8fa

Browse files
authored
Define debug method (#60)
1 parent 5e78256 commit 195c8fa

File tree

14 files changed

+273
-22
lines changed

14 files changed

+273
-22
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ set(SRCS
7171
src/Metric.cxx
7272
src/Backends/InfoLoggerBackend.cxx
7373
src/Backends/Flume.cxx
74+
src/Backends/StdOut.cxx
7475
src/DerivedMetrics.cxx
7576
src/ProcessMonitor.cxx
7677
src/ProcessDetails.cxx
@@ -139,6 +140,7 @@ enable_testing()
139140

140141
set(TEST_SRCS
141142
test/testMonitoring.cxx
143+
test/testMonitoringFactory.cxx
142144
test/testDerived.cxx
143145
test/testFlume.cxx
144146
test/testMetric.cxx

README.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,17 +92,18 @@ The library is accessible from `o2::monitoring` namespace.
9292
```cpp
9393
#include <MonitoringFactory.h>
9494
using namespace o2::monitoring;
95-
std::unique_ptr<Monitoring> monitoring = MonitoringFactory::Get("backend[-protocol]://host:port[?query]");
95+
std::unique_ptr<Monitoring> monitoring = MonitoringFactory::Get("backend[-protocol]://host:port[/verbosity][?query]");
9696
```
9797
See table below to find out how to create `URI` for each backend:
9898
99-
| Backend name | Transport | URI backend[-protocol] | URI query |
100-
| ------------ |:---------:|:----------------------:| ----------------:|
101-
| InfluxDB | HTTP | `influxdb-http` | `/write?db=<db>` |
102-
| InfluxDB | UDP | `influxdb-udp` | - |
103-
| ApMon | UDP | `apmon` | - |
104-
| InfoLogger | - | `infologger` | - |
105-
| Flume | UDP | `flume` | - |
99+
| Backend name | Transport | URI backend[-protocol] | URI query | Default verbosity |
100+
| ------------ |:---------:|:----------------------:|:----------------:| -----------------:|
101+
| InfluxDB | HTTP | `influxdb-http` | `/write?db=<db>` | `prod` |
102+
| InfluxDB | UDP | `influxdb-udp` | - | `prod` |
103+
| ApMon | UDP | `apmon` | - | `prod` |
104+
| Local InfoLogger | - | `infologger://` | - | `debug` |
105+
| InfoLogger | TCP | `infologger` | - | `prod` |
106+
| Flume | UDP | `flume` | - | `prod` |
106107
107108
Multiple backends may be used at the same time, URLs should be separated by `,` (comma).
108109
@@ -123,6 +124,19 @@ monitoring->send({10, "myMetricInt"});
123124
124125
Regarding `DerivedMetricMode` see [Calculating derived metrics](#calculating-derived-metrics).
125126
127+
### Debug metrics
128+
Debug metrics can be send by a similar method to above's `send`:
129+
```cpp
130+
debug(Metric&& metric)
131+
```
132+
133+
The difference is that debug metrics are only passed to backends which verbosity level is set to `debug`.
134+
135+
Each backend has its default verbosity (see backend in [Monitoring instance](#monitoring-instance) section). This can be changed by defining path of a backend URL:
136+
- `/prod` - only `send` metrics are passed to the backend
137+
- `/debug` - all the metrics are passed to the backend
138+
139+
126140
### Customized metrics
127141
Two additional methods can be chained the to `send(Metric&& metric)` in order to __insert custom tags__ or __set custom timestamp__:
128142
+ `addTags(std::vector<Tag>&& tags)`

examples/5-Benchmark.cxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ int main(int argc, char *argv[]) {
5353
monitoring->send({"string" + std::to_string(intDist(mt)), "stringMetric"});
5454
monitoring->send({doubleDist(mt), "doubleMetric"});
5555
monitoring->send({intDist(mt), "intMetric"});
56+
monitoring->debug({intDist(mt), "intMetricDebug"});
5657
std::this_thread::sleep_for(std::chrono::microseconds(sleep));
5758
}
5859
} else {

include/Monitoring/Backend.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,32 @@ namespace o2
1616
namespace monitoring
1717
{
1818

19+
namespace backend
20+
{
21+
enum class Verbosity { PROD, DEBUG };
22+
}
1923
/// \brief Backend pure virtual interface
2024
///
2125
/// Interface that allows to send a metric to remote backend.
2226
/// In addition, default tagset (for all handled metrics) can be created.
2327
class Backend
2428
{
29+
private:
30+
/// Verbosity level
31+
backend::Verbosity verbosityLevel;
32+
2533
public:
2634
/// Default constructor
27-
Backend() = default;
35+
Backend() { verbosityLevel = backend::Verbosity::PROD; }
2836

2937
/// Default destructor
3038
virtual ~Backend() = default;
39+
40+
/// Set verbosity level
41+
void setVerbosisty(backend::Verbosity level) { verbosityLevel = level; }
42+
43+
/// Get verbosity level
44+
backend::Verbosity getVerbosity() { return verbosityLevel; }
3145

3246
/// Sends metric via backend
3347
virtual void send(const Metric& metric) = 0;

include/Monitoring/Monitoring.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class Monitoring
5555
/// \param metric r-value to metric object
5656
/// \param mode Derived metric mode
5757
void send(Metric&& metric, DerivedMetricMode mode = DerivedMetricMode::NONE);
58-
58+
void debug(Metric&& metric);
5959
/// Sends multiple (not related to each other) metrics
6060
/// \param metrics vector of metrics
6161
void send(std::vector<Metric>&& metrics);
@@ -86,7 +86,7 @@ class Monitoring
8686

8787
/// Enables metric buffering
8888
/// \param size buffer size
89-
void enableBuffering(const unsigned int size = 20);
89+
void enableBuffering(const unsigned int size = 128);
9090

9191
/// Adds global tag
9292
/// \param name tag name

include/Monitoring/MonitoringFactory.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class MonitoringFactory
3232
private:
3333
/// Private constructor disallows to create instance of Factory
3434
MonitoringFactory() = default;
35+
36+
/// Sets backend verbosity based on the URL path
37+
static void SetVerbosity(std::string selected, std::unique_ptr<Backend>& backend);
3538
};
3639

3740
} // namespace monitoring

src/Backends/InfoLoggerBackend.cxx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ inline unsigned long InfoLoggerBackend::convertTimestamp(const std::chrono::time
2424
).count();
2525
}
2626

27-
InfoLoggerBackend::InfoLoggerBackend()
27+
InfoLoggerBackend::InfoLoggerBackend(std::string /*host*/, int /*port*/)
2828
{
29-
MonLogger::Get() << "Local InfoLogger backend initialized" << MonLogger::End();
29+
throw std::runtime_error("InfoLogger backend is not available");
3030
}
3131

3232
void InfoLoggerBackend::addGlobalTag(std::string name, std::string value)
@@ -65,9 +65,8 @@ void InfoLoggerBackend::send(const Metric& metric)
6565
if (!metricTags.empty()) {
6666
metricTags = "," + metricTags;
6767
}
68-
MonLogger::Get() << "[METRIC] " << metric.getName() << "," << metric.getType() << " " << metric.getValue()
69-
<< " " << convertTimestamp(metric.getTimestamp()) << " " << tagString << metricTags
70-
<< MonLogger::End();
68+
69+
// Send over InfoLogger protocol
7170
}
7271

7372
} // namespace backends

src/Backends/InfoLoggerBackend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class InfoLoggerBackend final : public Backend
2626
{
2727
public:
2828
/// Default constructor
29-
InfoLoggerBackend();
29+
InfoLoggerBackend(std::string /*host*/, int /*port*/);
3030

3131
/// Default destructor
3232
~InfoLoggerBackend() = default;

src/Backends/StdOut.cxx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
///
2+
/// \file StdOut.cxx
3+
/// \author Adam Wegrzynek <[email protected]>
4+
///
5+
6+
#include "StdOut.h"
7+
8+
#include <iostream>
9+
#include "../MonLogger.h"
10+
11+
namespace o2
12+
{
13+
/// ALICE O2 Monitoring system
14+
namespace monitoring
15+
{
16+
/// Monitoring backends
17+
namespace backends
18+
{
19+
20+
inline unsigned long StdOut::convertTimestamp(const std::chrono::time_point<std::chrono::system_clock>& timestamp)
21+
{
22+
return std::chrono::duration_cast <std::chrono::milliseconds>(
23+
timestamp.time_since_epoch()
24+
).count();
25+
}
26+
27+
StdOut::StdOut()
28+
{
29+
setVerbosisty(backend::Verbosity::DEBUG);
30+
MonLogger::Get() << "StdOut backend initialized" << MonLogger::End();
31+
}
32+
33+
void StdOut::addGlobalTag(std::string name, std::string value)
34+
{
35+
if (!tagString.empty()) {
36+
tagString += ",";
37+
}
38+
tagString += name + "=" + value;
39+
}
40+
41+
void StdOut::send(std::vector<Metric>&& metrics) {
42+
for (auto& m : metrics) {
43+
send(m);
44+
}
45+
}
46+
47+
void StdOut::sendMultiple(std::string measurement, std::vector<Metric>&& metrics)
48+
{
49+
for (auto& m : metrics) {
50+
std::string tempName = m.getName();
51+
m.setName(measurement + "-" + m.getName());
52+
send(m);
53+
m.setName(tempName);
54+
}
55+
}
56+
57+
void StdOut::send(const Metric& metric)
58+
{
59+
std::string metricTags{};
60+
for (const auto& tag : metric.getTags()) {
61+
if (!metricTags.empty()) {
62+
metricTags += ",";
63+
}
64+
metricTags += tag.name + "=" + tag.value;
65+
}
66+
if (!metricTags.empty()) {
67+
metricTags = "," + metricTags;
68+
}
69+
MonLogger::Get() << "[METRIC] " << metric.getName() << "," << metric.getType() << " " << metric.getValue()
70+
<< " " << convertTimestamp(metric.getTimestamp()) << " " << tagString << metricTags
71+
<< MonLogger::End();
72+
}
73+
74+
} // namespace backends
75+
} // namespace monitoring
76+
} // namespace o2

src/Backends/StdOut.h

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
///
2+
/// \file StdOut.h
3+
/// \author Adam Wegrzynek <[email protected]>
4+
///
5+
6+
#ifndef ALICEO2_MONITORING_BACKEND_STDOUT_H
7+
#define ALICEO2_MONITORING_BACKEND_STDOUT_H
8+
9+
#include "Monitoring/Backend.h"
10+
#include <string>
11+
12+
namespace o2
13+
{
14+
/// ALICE O2 Monitoring system
15+
namespace monitoring
16+
{
17+
/// Monitoring backends
18+
namespace backends
19+
{
20+
21+
/// \brief Backend that injects metrics to InfoLogger
22+
///
23+
/// InfoLogger does not support std::chrono::time_point therefore timestamps is converted to unsigned long
24+
class StdOut final : public Backend
25+
{
26+
public:
27+
/// Default constructor
28+
StdOut();
29+
30+
/// Default destructor
31+
~StdOut() = default;
32+
33+
/// Sends metric to InfoLogger library
34+
/// \param metric reference to metric object
35+
void send(const Metric& metric) override;
36+
37+
/// Sends multiple metrics not related to each other
38+
/// \@param metrics vector of metrics
39+
void send(std::vector<Metric>&& metrics) override;
40+
41+
/// Sending multiple metrics is NOT supported by the InfoLogger therefore it falls back to sending metric one by one
42+
/// \param measurement measurement name
43+
/// \param metrics list of metrics
44+
void sendMultiple(std::string measurement, std::vector<Metric>&& metrics) override;
45+
46+
/// Adds tag
47+
/// \param name tag name
48+
/// \param value tag value
49+
void addGlobalTag(std::string name, std::string value) override;
50+
51+
private:
52+
/// Converts timestamp to unsigned long (miliseconds from epoch)
53+
/// \param timestamp timestamp in std::chrono::time_point format
54+
/// \return timestamp as unsigned long (miliseconds from epoch)
55+
unsigned long convertTimestamp(const std::chrono::time_point<std::chrono::system_clock>& timestamp);
56+
57+
std::string tagString; ///< Global tagset (common for each metric)
58+
};
59+
60+
} // namespace backends
61+
} // namespace monitoring
62+
} // namespace o2
63+
64+
#endif // ALICEO2_MONITORING_BACKEND_STDOUT_H

0 commit comments

Comments
 (0)