2222#include < iostream>
2323#include < map>
2424#include < stdexcept>
25+ #include < string>
26+ #include < nlohmann/json.hpp>
2527
2628using namespace esi ;
2729
2830void printInfo (std::ostream &os, AcceleratorConnection &acc, bool details);
2931void printHier (std::ostream &os, AcceleratorConnection &acc, bool details);
3032void printTelemetry (std::ostream &os, AcceleratorConnection &acc);
33+ void printTelemetryJson (std::ostream &os, AcceleratorConnection &acc);
3134
3235int main (int argc, const char *argv[]) {
3336 CliParser cli (" esiquery" );
@@ -44,8 +47,11 @@ int main(int argc, const char *argv[]) {
4447 CLI::App *hierSub = cli.add_subcommand (" hier" , " Print ESI system hierarchy" );
4548 hierSub->add_flag (" --details" , hierDetails,
4649 " Print detailed information about the system" );
47- CLI::App *telemetrySub =
50+ bool telemetryJson = false ;
51+ CLI::App *telemetrySub =
4852 cli.add_subcommand (" telemetry" , " Print ESI system telemetry information" );
53+ telemetrySub->add_flag (" --json" , telemetryJson,
54+ " Dump telemetry information as JSON" );
4955
5056 if (int rc = cli.esiParse (argc, argv))
5157 return rc;
@@ -63,8 +69,12 @@ int main(int argc, const char *argv[]) {
6369 printInfo (std::cout, *acc, infoDetails);
6470 else if (*hierSub)
6571 printHier (std::cout, *acc, hierDetails);
66- else if (*telemetrySub)
67- printTelemetry (std::cout, *acc);
72+ else if (*telemetrySub) {
73+ if (telemetryJson)
74+ printTelemetryJson (std::cout, *acc);
75+ else
76+ printTelemetry (std::cout, *acc);
77+ }
6878 return 0 ;
6979 } catch (std::exception &e) {
7080 ctxt.getLogger ().error (" esiquery" , e.what ());
@@ -159,6 +169,74 @@ void printHier(std::ostream &os, AcceleratorConnection &acc, bool details) {
159169 printInstance (os, design, /* indent=*/ " " , details);
160170}
161171
172+ static void insertTelemetryValue (nlohmann::json &root, const AppIDPath &path,
173+ uint64_t value) {
174+ if (path.empty ()) {
175+ root[" __value" ] = value;
176+ return ;
177+ }
178+
179+ nlohmann::json *current = &root;
180+ for (size_t i = 0 ; i < path.size (); ++i) {
181+ const std::string key = path[i].toString ();
182+ nlohmann::json &next = (*current)[key];
183+ if (i == path.size () - 1 ) {
184+ if (next.is_object ())
185+ next[" __value" ] = value;
186+ else
187+ next = value;
188+ } else {
189+ if (!next.is_object ()) {
190+ nlohmann::json previous = next;
191+ next = nlohmann::json::object ();
192+ if (!previous.is_null ())
193+ next[" __value" ] = previous;
194+ }
195+ current = &next;
196+ }
197+ }
198+ }
199+
200+ static void collapseTelemetryJson (nlohmann::json &node) {
201+ if (!node.is_object ())
202+ return ;
203+
204+ for (auto it = node.begin (); it != node.end (); ++it)
205+ collapseTelemetryJson (it.value ());
206+
207+ if (node.size () == 1 && node.contains (" __value" )) {
208+ nlohmann::json value = node[" __value" ];
209+ node = value;
210+ }
211+ }
212+
213+ void printTelemetryJson (std::ostream &os, AcceleratorConnection &acc) {
214+ Manifest manifest (acc.getCtxt (),
215+ acc.getService <services::SysInfo>()->getJsonManifest ());
216+ auto accel = manifest.buildAccelerator (acc);
217+ acc.getServiceThread ()->addPoll (*accel);
218+
219+ auto *telemetry = acc.getService <services::TelemetryService>();
220+ if (!telemetry) {
221+ os << nlohmann::json{{" error" , " No telemetry service found" }}.dump (2 )
222+ << std::endl;
223+ return ;
224+ }
225+
226+ const std::map<AppIDPath, services::TelemetryService::Metric *>
227+ &telemetryPorts = telemetry->getTelemetryPorts ();
228+
229+ nlohmann::json root = nlohmann::json::object ();
230+ for (const auto &[id, port] : telemetryPorts) {
231+ port->connect ();
232+ uint64_t value = *port->read ().get ().as <uint64_t >();
233+ insertTelemetryValue (root, id, value);
234+ }
235+
236+ collapseTelemetryJson (root);
237+ os << root.dump (2 ) << std::endl;
238+ }
239+
162240void printTelemetry (std::ostream &os, AcceleratorConnection &acc) {
163241 Manifest manifest (acc.getCtxt (),
164242 acc.getService <services::SysInfo>()->getJsonManifest ());
0 commit comments