#include <iostream>
#include "iputils.hh"
#include "rec_channel.hh"
+#include "rec_metrics.hh"
#include "arguments.hh"
#include "misc.hh"
#include "syncres.hh"
DNSName canon = apiNameToDNSName(req->getvars["domain"]);
bool subtree = (req->getvars.count("subtree") > 0 && req->getvars["subtree"].compare("true") == 0);
- int count = broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, canon, subtree));
- count += broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, canon, subtree));
- count += broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, canon, subtree));
+ int count = broadcastAccFunction<uint64_t>(std::bind(pleaseWipeCache, canon, subtree, 0xffff));
+ count += broadcastAccFunction<uint64_t>(std::bind(pleaseWipePacketCache, canon, subtree, 0xffff));
+ count += broadcastAccFunction<uint64_t>(std::bind(pleaseWipeAndCountNegCache, canon, subtree));
resp->setBody(Json::object {
{ "count", count },
{ "result", "Flushed cache." }
auto zone = luaconf->dfe.getZone(i);
if (zone == nullptr)
continue;
- auto name = zone->getName();
- auto stats = getRPZZoneStats(*name);
+ const auto& name = zone->getName();
+ auto stats = getRPZZoneStats(name);
if (stats == nullptr)
continue;
Json::object zoneInfo = {
{"last_update", (double)stats->d_lastUpdate},
{"serial", (double)stats->d_serial},
};
- ret[*name] = zoneInfo;
+ ret[name] = zoneInfo;
}
resp->setBody(ret);
}
+
+static void prometheusMetrics(HttpRequest *req, HttpResponse *resp) {
+ static MetricDefinitionStorage s_metricDefinitions;
+
+ if (req->method != "GET")
+ throw HttpMethodNotAllowedException();
+
+ registerAllStats();
+
+
+ std::ostringstream output;
+ typedef map <string, string> varmap_t;
+ varmap_t varmap = getAllStatsMap(
+ StatComponent::API); // Argument controls blacklisting of any stats. So stats-api-blacklist will be used to block returned stats.
+ for (const auto &tup : varmap) {
+ std::string metricName = tup.first;
+
+ // Prometheus suggest using '_' instead of '-'
+ std::string prometheusMetricName = "pdns_recursor_" + boost::replace_all_copy(metricName, "-", "_");
+
+ MetricDefinition metricDetails;
+
+ if (s_metricDefinitions.getMetricDetails(metricName, metricDetails)) {
+ std::string prometheusTypeName = s_metricDefinitions.getPrometheusStringMetricType(
+ metricDetails.prometheusType);
+
+ if (prometheusTypeName.empty()) {
+ continue;
+ }
+
+ // for these we have the help and types encoded in the sources:
+ output << "# HELP " << prometheusMetricName << " " << metricDetails.description << "\n";
+ output << "# TYPE " << prometheusMetricName << " " << prometheusTypeName << "\n";
+ }
+ output << prometheusMetricName << " " << tup.second << "\n";
+ }
+
+ resp->body = output.str();
+ resp->headers["Content-Type"] = "text/plain";
+ resp->status = 200;
+
+}
+
+
#include "htmlfiles.h"
static void serveStuff(HttpRequest* req, HttpResponse* resp)
{
registerAllStats();
- d_ws = new AsyncWebServer(fdm, arg()["webserver-address"], arg().asNum("webserver-port"));
+ d_ws = std::unique_ptr<AsyncWebServer>(new AsyncWebServer(fdm, arg()["webserver-address"], arg().asNum("webserver-port")));
d_ws->setApiKey(arg()["api-key"]);
d_ws->setPassword(arg()["webserver-password"]);
d_ws->setLogLevel(arg()["webserver-loglevel"]);
d_ws->bind();
// legacy dispatch
- d_ws->registerApiHandler("/jsonstat", boost::bind(&RecursorWebServer::jsonstat, this, _1, _2), true);
+ d_ws->registerApiHandler("/jsonstat", std::bind(&RecursorWebServer::jsonstat, this, std::placeholders::_1, std::placeholders::_2), true);
d_ws->registerApiHandler("/api/v1/servers/localhost/cache/flush", &apiServerCacheFlush);
d_ws->registerApiHandler("/api/v1/servers/localhost/config/allow-from", &apiServerConfigAllowFrom);
d_ws->registerApiHandler("/api/v1/servers/localhost/config", &apiServerConfig);
for(const auto& u : g_urlmap)
d_ws->registerWebHandler("/"+u.first, serveStuff);
d_ws->registerWebHandler("/", serveStuff);
+ d_ws->registerWebHandler("/metrics", prometheusMetrics);
d_ws->go();
}
void AsyncServer::asyncWaitForConnections(FDMultiplexer* fdm, const newconnectioncb_t& callback)
{
d_asyncNewConnectionCallback = callback;
- fdm->addReadFD(d_server_socket.getHandle(), boost::bind(&AsyncServer::newConnection, this));
+ fdm->addReadFD(d_server_socket.getHandle(), std::bind(&AsyncServer::newConnection, this));
}
void AsyncServer::newConnection()
auto server = std::dynamic_pointer_cast<AsyncServer>(d_server);
if (!server)
return;
- server->asyncWaitForConnections(d_fdm, boost::bind(&AsyncWebServer::serveConnection, this, _1));
+ server->asyncWaitForConnections(d_fdm, std::bind(&AsyncWebServer::serveConnection, this, std::placeholders::_1));
}