Skip to content

Commit ca3e2cc

Browse files
committed
DPL: use rapidjson to dump metrics
1 parent a8e788c commit ca3e2cc

File tree

3 files changed

+63
-60
lines changed

3 files changed

+63
-60
lines changed

Framework/Core/include/Framework/DeviceMetricsInfo.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,11 @@ struct DeviceMetricsInfo {
154154
std::vector<MetricsStorage<StringMetric>> stringMetrics; // We do not keep so many strings as metrics as history is less relevant.
155155
std::vector<MetricsStorage<float>> floatMetrics;
156156
std::vector<MetricsStorage<int8_t>> enumMetrics;
157-
std::vector<std::array<size_t, metricStorageSize<int>()>> intTimestamps;
158-
std::vector<std::array<size_t, metricStorageSize<uint64_t>()>> uint64Timestamps;
159-
std::vector<std::array<size_t, metricStorageSize<float>()>> floatTimestamps;
160-
std::vector<std::array<size_t, metricStorageSize<StringMetric>()>> stringTimestamps;
161-
std::vector<std::array<size_t, metricStorageSize<int8_t>()>> enumTimestamps;
157+
std::vector<TimestampsStorage<int>> intTimestamps;
158+
std::vector<TimestampsStorage<uint64_t>> uint64Timestamps;
159+
std::vector<TimestampsStorage<float>> floatTimestamps;
160+
std::vector<TimestampsStorage<StringMetric>> stringTimestamps;
161+
std::vector<TimestampsStorage<int8_t>> enumTimestamps;
162162
std::vector<float> max;
163163
std::vector<float> min;
164164
std::vector<float> average;

Framework/Core/src/ResourcesMonitoringHelper.cxx

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
// In applying this license CERN does not waive the privileges and immunities
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
11-
1211
#include "ResourcesMonitoringHelper.h"
1312
#include "Framework/DeviceMetricsInfo.h"
14-
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
15-
#include <boost/property_tree/json_parser.hpp>
16-
#include <fstream>
13+
#include <rapidjson/prettywriter.h>
14+
#include <rapidjson/ostreamwrapper.h>
15+
16+
#include <ostream>
17+
#include <string>
1718
#include <string_view>
1819
#include <algorithm>
1920
#include <cassert>
@@ -22,34 +23,28 @@
2223
using namespace o2::framework;
2324

2425
template <typename T>
25-
inline static T retriveValue(T val)
26+
void fillNodeWithValue(rapidjson::Writer<rapidjson::OStreamWrapper>& w,
27+
size_t filledMetrics,
28+
MetricsStorage<T> const& metricsStorage,
29+
TimestampsStorage<T> const& timestampsStorage)
2630
{
27-
return val;
28-
}
29-
30-
inline static std::string retriveValue(const std::reference_wrapper<const StringMetric> val)
31-
{
32-
return std::string(val.get().data);
33-
}
34-
35-
template <typename T, typename TIMESTAMPS>
36-
boost::property_tree::ptree fillNodeWithValue(const DeviceMetricsInfo& deviceMetrics,
37-
const T& metricsStorage, const TIMESTAMPS& timestampsStorage, size_t labelIndex, size_t storeIndex)
38-
{
39-
unsigned int loopRange = std::min(deviceMetrics.metrics[labelIndex].filledMetrics, metricsStorage[storeIndex].size());
40-
boost::property_tree::ptree metricNode;
31+
unsigned int loopRange = std::min(filledMetrics, metricsStorage.size());
4132

33+
w.StartArray();
4234
for (unsigned int idx = 0; idx < loopRange; ++idx) {
43-
boost::property_tree::ptree values;
44-
values.add("timestamp", timestampsStorage[storeIndex][idx]);
35+
w.StartObject();
36+
w.Key("timestamp");
37+
std::string s = std::to_string(timestampsStorage[idx]);
38+
w.String(s.c_str(), s.size());
39+
w.Key("value");
4540
if constexpr (std::is_arithmetic_v<T>) {
46-
values.add("value", std::to_string(retriveValue(std::cref(metricsStorage[storeIndex][idx]))));
41+
w.String(std::to_string(metricsStorage[idx]).c_str());
4742
} else {
48-
values.add("value", retriveValue(std::cref(metricsStorage[storeIndex][idx])));
43+
w.String(metricsStorage[idx].data);
4944
}
50-
metricNode.push_back(std::make_pair("", values));
45+
w.EndObject();
5146
}
52-
return metricNode;
47+
w.EndArray();
5348
}
5449

5550
bool ResourcesMonitoringHelper::dumpMetricsToJSON(const std::vector<DeviceMetricsInfo>& metrics,
@@ -58,19 +53,23 @@ bool ResourcesMonitoringHelper::dumpMetricsToJSON(const std::vector<DeviceMetric
5853
std::vector<std::regex> const& performanceMetricsRegex,
5954
std::ostream& out) noexcept
6055
{
61-
6256
assert(metrics.size() == specs.size());
6357

6458
if (metrics.empty()) {
6559
return false;
6660
}
6761

68-
boost::property_tree::ptree root;
69-
for (unsigned int idx = 0; idx < metrics.size(); ++idx) {
62+
rapidjson::OStreamWrapper osw(out);
63+
rapidjson::PrettyWriter<rapidjson::OStreamWrapper> w(osw);
64+
65+
// Top level obejct for all the metrics
66+
w.StartObject();
7067

68+
for (unsigned int idx = 0; idx < metrics.size(); ++idx) {
69+
w.Key(specs[idx].id.c_str());
7170
const auto& deviceMetrics = metrics[idx];
72-
boost::property_tree::ptree deviceRoot;
7371

72+
w.StartObject();
7473
for (size_t mi = 0; mi < deviceMetrics.metricLabels.size(); mi++) {
7574
std::string_view metricLabel{deviceMetrics.metricLabels[mi].label, deviceMetrics.metricLabels[mi].size};
7675

@@ -83,40 +82,42 @@ bool ResourcesMonitoringHelper::dumpMetricsToJSON(const std::vector<DeviceMetric
8382
}
8483
auto storeIdx = deviceMetrics.metrics[mi].storeIdx;
8584

85+
size_t filledMetrics = deviceMetrics.metrics[mi].filledMetrics;
8686
if (deviceMetrics.metrics[mi].filledMetrics == 0) {
8787
continue;
8888
}
89-
// if so
90-
91-
boost::property_tree::ptree metricNode;
92-
89+
w.Key(metricLabel.data(), metricLabel.size());
9390
switch (deviceMetrics.metrics[mi].type) {
9491
case MetricType::Int:
95-
metricNode = fillNodeWithValue(deviceMetrics, deviceMetrics.intMetrics, deviceMetrics.intTimestamps, mi, storeIdx);
92+
fillNodeWithValue(w, filledMetrics, deviceMetrics.intMetrics[storeIdx],
93+
deviceMetrics.intTimestamps[storeIdx]);
9694
break;
9795

9896
case MetricType::Float:
99-
metricNode = fillNodeWithValue(deviceMetrics, deviceMetrics.floatMetrics, deviceMetrics.floatTimestamps, mi, storeIdx);
97+
fillNodeWithValue(w, filledMetrics, deviceMetrics.floatMetrics[storeIdx],
98+
deviceMetrics.floatTimestamps[storeIdx]);
10099
break;
101100

102101
case MetricType::String:
103-
metricNode = fillNodeWithValue(deviceMetrics, deviceMetrics.stringMetrics, deviceMetrics.stringTimestamps, mi, storeIdx);
102+
fillNodeWithValue(w, filledMetrics, deviceMetrics.stringMetrics[storeIdx],
103+
deviceMetrics.stringTimestamps[storeIdx]);
104104
break;
105105

106106
case MetricType::Uint64:
107-
metricNode = fillNodeWithValue(deviceMetrics, deviceMetrics.uint64Metrics, deviceMetrics.uint64Timestamps, mi, storeIdx);
107+
fillNodeWithValue(w, filledMetrics, deviceMetrics.uint64Metrics[storeIdx],
108+
deviceMetrics.uint64Timestamps[storeIdx]);
108109
break;
109110

110111
default:
111112
continue;
112113
}
113-
deviceRoot.add_child(std::string(metricLabel), metricNode);
114114
}
115115

116-
root.add_child(specs[idx].id, deviceRoot);
116+
w.EndObject();
117117
}
118118

119-
boost::property_tree::ptree driverRoot;
119+
w.Key("driver");
120+
w.StartObject();
120121
for (size_t mi = 0; mi < driverMetrics.metricLabels.size(); mi++) {
121122
std::string_view const metricLabel{driverMetrics.metricLabels[mi].label, driverMetrics.metricLabels[mi].size};
122123
auto same = [metricLabel](std::regex const& matcher) -> bool {
@@ -130,39 +131,39 @@ bool ResourcesMonitoringHelper::dumpMetricsToJSON(const std::vector<DeviceMetric
130131

131132
auto storeIdx = driverMetrics.metrics[mi].storeIdx;
132133
// and if data is there
133-
if (driverMetrics.metrics[mi].filledMetrics == 0) {
134+
size_t filledMetrics = driverMetrics.metrics[mi].filledMetrics;
135+
if (filledMetrics == 0) {
134136
continue;
135137
}
136138

137-
// if so
138-
boost::property_tree::ptree metricNode;
139-
139+
w.Key(metricLabel.data(), metricLabel.size());
140140
switch (driverMetrics.metrics[mi].type) {
141141
case MetricType::Int:
142-
metricNode = fillNodeWithValue(driverMetrics, driverMetrics.intMetrics, driverMetrics.intTimestamps, mi, storeIdx);
142+
fillNodeWithValue(w, filledMetrics, driverMetrics.intMetrics[storeIdx],
143+
driverMetrics.intTimestamps[storeIdx]);
143144
break;
144145

145146
case MetricType::Float:
146-
metricNode = fillNodeWithValue(driverMetrics, driverMetrics.floatMetrics, driverMetrics.floatTimestamps, mi, storeIdx);
147+
fillNodeWithValue(w, filledMetrics, driverMetrics.floatMetrics[storeIdx],
148+
driverMetrics.floatTimestamps[storeIdx]);
147149
break;
148150

149151
case MetricType::String:
150-
metricNode = fillNodeWithValue(driverMetrics, driverMetrics.stringMetrics, driverMetrics.stringTimestamps, mi, storeIdx);
152+
fillNodeWithValue(w, filledMetrics, driverMetrics.stringMetrics[storeIdx],
153+
driverMetrics.stringTimestamps[storeIdx]);
151154
break;
152155

153156
case MetricType::Uint64:
154-
metricNode = fillNodeWithValue(driverMetrics, driverMetrics.uint64Metrics, driverMetrics.uint64Timestamps, mi, storeIdx);
157+
fillNodeWithValue(w, filledMetrics, driverMetrics.uint64Metrics[storeIdx],
158+
driverMetrics.uint64Timestamps[storeIdx]);
155159
break;
156160

157161
default:
158162
continue;
159163
}
160-
driverRoot.add_child(std::string{metricLabel}, metricNode);
161164
}
162-
163-
root.add_child("driver", driverRoot);
164-
165-
boost::property_tree::json_parser::write_json(out, root);
165+
w.EndObject();
166+
w.EndObject();
166167

167168
return true;
168169
}

Framework/Core/test/test_ResourcesMonitoringHelpers.cxx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ TEST_CASE("StreamMetrics")
166166
ResourcesMonitoringHelper::dumpMetricsToJSON(metrics,
167167
driverMetrics, specs, performanceMetrics,
168168
streamer);
169-
REQUIRE(streamer.str() == R"JSON({
169+
std::string streamed = streamer.str();
170+
std::string expected = R"JSON({
170171
"someDevice": {
171172
"ckey": [
172173
{
@@ -266,5 +267,6 @@ TEST_CASE("StreamMetrics")
266267
]
267268
}
268269
}
269-
)JSON");
270+
)JSON";
271+
REQUIRE(std::regex_replace(streamed, std::regex(R"(\s+)"), "") == std::regex_replace(expected, std::regex(R"(\s+)"), ""));
270272
}

0 commit comments

Comments
 (0)