From: Christian Hofstaedtler Date: Tue, 28 Jan 2014 21:02:25 +0000 (+0100) Subject: webserver: implement statistics, fix config X-Git-Tag: rec-3.6.0-rc1~213^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a45303b8667a492863f010cf10d879ecfaa9fc13;p=pdns webserver: implement statistics, fix config Per the specification. --- diff --git a/pdns/ws.cc b/pdns/ws.cc index e2777bc40..4832da300 100644 --- a/pdns/ws.cc +++ b/pdns/ws.cc @@ -420,25 +420,70 @@ static void apiServerConfig(HttpRequest* req, HttpResponse* resp) { throw HttpMethodNotAllowedException(); vector items = ::arg().list(); + string value; Document doc; doc.SetArray(); - BOOST_FOREACH(const string& var, items) { - Value kv, key, value; - kv.SetArray(); - key.SetString(var.c_str(), var.length()); - kv.PushBack(key, doc.GetAllocator()); - - if(var.find("password") != string::npos) - value="*****"; + BOOST_FOREACH(const string& item, items) { + Value jitem; + jitem.SetObject(); + jitem.AddMember("type", "ConfigSetting", doc.GetAllocator()); + + Value jname(item.c_str(), doc.GetAllocator()); + jitem.AddMember("name", jname, doc.GetAllocator()); + + if(item.find("password") != string::npos) + value = "***"; else - value.SetString(::arg()[var].c_str(), ::arg()[var].length(), doc.GetAllocator()); + value = ::arg()[item]; - kv.PushBack(value, doc.GetAllocator()); - doc.PushBack(kv, doc.GetAllocator()); + Value jvalue(value.c_str(), doc.GetAllocator()); + jitem.AddMember("value", jvalue, doc.GetAllocator()); + + doc.PushBack(jitem, doc.GetAllocator()); } resp->body = makeStringFromDocument(doc); } +static void apiServerStatistics(HttpRequest* req, HttpResponse* resp) { + if(req->method != "GET") + throw HttpMethodNotAllowedException(); + + vector items = S.getEntries(); + string value; + Document doc; + doc.SetArray(); + BOOST_FOREACH(const string& item, items) { + Value jitem; + jitem.SetObject(); + jitem.AddMember("type", "StatisticItem", doc.GetAllocator()); + + Value jname(item.c_str(), doc.GetAllocator()); + jitem.AddMember("name", jname, doc.GetAllocator()); + + value = lexical_cast(S.read(item)); + + Value jvalue(value.c_str(), doc.GetAllocator()); + jitem.AddMember("value", jvalue, doc.GetAllocator()); + + doc.PushBack(jitem, doc.GetAllocator()); + } + + // add uptime + // TODO: this is a hack. should we move this elsewhere? + { + Value jitem; + jitem.SetObject(); + jitem.AddMember("type", "StatisticItem", doc.GetAllocator()); + jitem.AddMember("name", "uptime", doc.GetAllocator()); + value = lexical_cast(time(0) - s_starttime); + Value jvalue(value.c_str(), doc.GetAllocator()); + jitem.AddMember("value", jvalue, doc.GetAllocator()); + doc.PushBack(jitem, doc.GetAllocator()); + } + + resp->body = makeStringFromDocument(doc); +} + static void apiServerSearchLog(HttpRequest* req, HttpResponse* resp) { if(req->method != "GET") throw HttpMethodNotAllowedException(); @@ -610,42 +655,7 @@ void StatWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) req->parameters.erase("command"); } - if(command=="get") { - if(req->parameters.empty()) { - vector entries = S.getEntries(); - BOOST_FOREACH(string& ent, entries) { - req->parameters[ent]; - } - req->parameters["version"]; - req->parameters["uptime"]; - } - - string variable, value; - - Document doc; - doc.SetObject(); - for(varmap_t::const_iterator iter = req->parameters.begin(); iter != req->parameters.end() ; ++iter) { - variable = iter->first; - if(variable == "version") { - value = VERSION; - } - else if(variable == "uptime") { - value = lexical_cast(time(0) - s_starttime); - } - else - value = lexical_cast(S.read(variable)); - Value jval; - jval.SetString(value.c_str(), value.length(), doc.GetAllocator()); - doc.AddMember(variable.c_str(), jval, doc.GetAllocator()); - } - resp->body = makeStringFromDocument(doc); - return; - } - else if(command=="config") { - apiServerConfig(req, resp); - return; - } - else if(command == "flush-cache") { + if(command == "flush-cache") { extern PacketCache PC; int number; if(req->parameters["domain"].empty()) @@ -865,6 +875,7 @@ void StatWebServer::launch() if(::arg().mustDo("experimental-json-interface")) { registerApiHandler("/servers/localhost/config", &apiServerConfig); registerApiHandler("/servers/localhost/search-log", &apiServerSearchLog); + registerApiHandler("/servers/localhost/statistics", &apiServerStatistics); registerApiHandler("/servers/localhost/zones/", &apiServerZoneDetail); registerApiHandler("/servers/localhost/zones", &apiServerZones); registerApiHandler("/servers/localhost", &apiServerDetail); diff --git a/regression-tests.api/test_Servers.py b/regression-tests.api/test_Servers.py index 561be5a49..3895d87b5 100644 --- a/regression-tests.api/test_Servers.py +++ b/regression-tests.api/test_Servers.py @@ -29,6 +29,11 @@ class Servers(ApiTestCase): def test_ReadConfig(self): r = self.session.get(self.url("/servers/localhost/config")) self.assertSuccessJson(r) - data = dict(r.json()) - self.assertIn('version', data) - print data + data = dict([(r['name'], r['value']) for r in r.json()]) + self.assertIn('daemon', data) + + def test_ReadStatistics(self): + r = self.session.get(self.url("/servers/localhost/statistics")) + self.assertSuccessJson(r) + data = dict([(r['name'], r['value']) for r in r.json()]) + self.assertIn('uptime', data)