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>
2223using namespace o2 ::framework;
2324
2425template <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
5550bool 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}
0 commit comments