Skip to content
7 changes: 6 additions & 1 deletion common/include/villas/hist.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@

#pragma once

#include <string>
#include <vector>

#include<string>
#include <jansson.h>
Comment on lines +12 to 13
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#include<string>
#include <jansson.h>
#include<string>
#include <jansson.h>

We usually try to group headers into these sections separated by an empty line

  • libstdc++
  • libc
  • third-party
  • VILLASnode

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are also missing a space after in include<string>.

@stv0g this grouping is not part of the contributor guidelines, so you shouldn't enforce it :)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, Its also something which we will fix repo-wide with the new clang-tidy fixes Philipp is working on..

I did not mention the missing space, as it will be fixed by clang-format.


#include <villas/log.hpp>
Expand Down Expand Up @@ -49,6 +50,7 @@ class Hist {
// Print ASCII style plot of histogram.
void plot(Logger logger) const;

void test();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused?

// Dump histogram data in Matlab format.
//
// @return The string containing the dump. The caller is responsible to free() the buffer.
Expand All @@ -60,6 +62,9 @@ class Hist {
// Write the histogram in JSON format to file \p f.
int dumpJson(FILE *f) const;

std::string toPrometheusText(std::string metric_name,
std::string node_name) const;

// Build a libjansson / JSON object of the histogram.
json_t *toJson() const;

Expand Down
25 changes: 25 additions & 0 deletions common/lib/hist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,31 @@ void Hist::plot(Logger logger) const {
}
}

std::string Hist::toPrometheusText(std::string metric_name,
std::string node_name) const {
std::stringstream base;
base << "#TYPE HISTOGRAM " << metric_name;
// Needed because Prometheus understands quantiles.
int s = data.size();
Hist::cnt_t cumsum = 0;
for (int i = 0; i < s; i++) {
cumsum += data[i];
base << "\n"
<< metric_name << " {node=\"" << node_name << "\" le=\""
<< ((double)i + 1) / s << "\"} " << cumsum;
}

base << "\n"
<< metric_name << " {node=\"" << node_name << "\" le=\"+Inf\"} " << total
<< "\n"
<< metric_name << "_count "
<< " {node=\"" << node_name << "\"} " << total;

//next line is problematic because buckets have no associated values ?
//base +="\n"+metric_name+"_count "+" {node=\""+node_name+"} "+std::to_string(ttl);
return base.str();
}

char *Hist::dump() const {
char *buf = new char[128];
if (!buf)
Expand Down
1 change: 1 addition & 0 deletions lib/api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ set(API_SRC
requests/node_stats.cpp
requests/node_stats_reset.cpp
requests/node_file.cpp
requests/metrics.cpp
requests/paths.cpp
requests/path_info.cpp
requests/path_action.cpp
Expand Down
65 changes: 65 additions & 0 deletions lib/api/requests/metrics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* The metrics API ressource.
*
* Author: Steffen Vogel <post@steffenvogel.de>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please put your name here :)

* Author: Youssef Nakti <naktiyoussef@proton.me>
* SPDX-FileCopyrightText: 2014-2023 Institute for Automation of Complex Power Systems, RWTH Aachen University
* SPDX-License-Identifier: Apache-2.0
*/

#include <chrono>

#include <jansson.h>

#include <villas/api/request.hpp>
#include <villas/api/response.hpp>
#include <villas/api/session.hpp>
#include <villas/node.hpp>
#include <villas/stats.hpp>
#include <villas/super_node.hpp>
#include <villas/utils.hpp>

namespace villas {
namespace node {
namespace api {

class MetricsRequest : public Request {
public:
using Request::Request;

virtual Response *execute() {
if (method != Session::Method::GET)
throw InvalidMethod(this);

if (body != nullptr)
throw BadRequest("The metrics endpoint does not accept any body data");

std::stringstream res_stream;
NodeList node_list = session->getSuperNode()->getNodes();
for (Node *node : node_list) {
auto stats = node->getStats();
if (!stats)
continue;
std::string node_name = node->getNameShort();
for (auto &metric : Stats::metrics) {
std::string metric_name = metric.second.name;
std::replace(metric_name.begin(), metric_name.end(), '.', '_');
res_stream << stats->getHistogram(metric.first)
.toPrometheusText(metric_name, node->getNameShort())
<< "\n";
}
}
auto text_res = res_stream.str();
return new Response(session, HTTP_STATUS_OK, "text/plain; charset=UTF-8",
Buffer(text_res.c_str(), text_res.size()));
}
};

// Register API request
static char n[] = "metrics";
static char r[] = "/metrics";
static char d[] = "Get stats of all nodes in Prometheus metrics format";
static RequestPlugin<MetricsRequest, n, r, d> p;

} // namespace api
} // namespace node
} // namespace villas