diff --git a/master/status_httpd.cc b/master/status_httpd.cc index 3c807783ccbdde7415aed9198d201e93fd8bcb9d..e1e1e6793ff2a8fd8cffa2b52759fd5b985b0c9e 100644 --- a/master/status_httpd.cc +++ b/master/status_httpd.cc @@ -1,15 +1,62 @@ // $Id$ +#include <numeric> #include <iostream> #include <sstream> #include <string> #include "status_httpd.h" +using namespace std; + namespace dos { +static void normalize(vector<double>& values) +{ + ostringstream ds; + double min = min_element(values.begin(), values.end()); + double max = max_element(values.begin(), values.end()); + vector<double>::iterator i; + for (i = values.begin(); i != values.end(); ++i) + *i = (*i - min) / (max - min); +} + +static string to_dataset(vector<double>& values) +{ + static const char vchar[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + normalize(values); + ostringstream ds; + vector<double>::const_iterator i; + for (i = values.begin(); i != values.end(); ++i) + ds << vchar[static_cast<int>(100 * (*i))]; + return ds.str(); +} + +static string qps_graph(const vector<QpsTuple>& qps_values, + int width=500, int height=200) +{ + ostringstream url; + url << "http://chart.apis.google.com/chart" + << "?chs=" << width << "x" << height + << "&cht=lc"; + + vector<double> stdup, avg, stddown; + vector<QpsTuple>::const_iterator i; + for (i = qps_values.begin(); i != qps_values.end(); ++i) { + stdup.push_back((*i).value + (*i).std_dev); + avg.push_back((*i).value); + stddown.push_back((*i).value - (*i).std_dev); + } + + url << "&chd=s:" + << to_dataset(stdup) << "," + << to_dataset(avg) << "," + << to_dataset(stddown); +} + void StatusHttpd::handle_status(evhttp_request *req) { - std::ostringstream resp; + ostringstream resp; resp << "<?xml version=\"1.0\"?>\n" << "<html lang=\"en\">\n" @@ -19,13 +66,20 @@ void StatusHttpd::handle_status(evhttp_request *req) resp << "<h1>NoDDoS Master</h1>"; - resp << "<p>Global QPS: <b>" << logic->get_qps() << "</b></p>" + vector<QpsTuple> qps_values; + logic->get_store()->read_stats(qps_values, 24); + string graph_url = qps_graph(qps_values); + resp << "<table><tr><td valign=\"top\">" + << "<p>Global QPS: <b>" << logic->get_qps() << "</b></p>" << "<p>Global status: <b>" << logic->get_status().str() - << "</b></p>\n"; + << "</b></p>\n" + << "</td><td>" + << "<img src=\"" << graph_url << "\" border=\"0\"/>" + << "</td></tr></table>\n"; resp << "<h3>Nodes</h3><ul>"; - std::vector<std::string> nodes = logic->nodes(); - std::vector<std::string>::const_iterator i; + vector<string> nodes = logic->nodes(); + vector<string>::const_iterator i; for (i = nodes.begin(); i != nodes.end(); i++) resp << "<li><a href=\"http://" << (*i) << "/\">" << (*i) << "</a></li>"; @@ -33,7 +87,7 @@ void StatusHttpd::handle_status(evhttp_request *req) resp << "<h3>Blacklisted hosts</h3><table class=\"d\">" << "<thead><tr><th>IP</th></tr></thead><tbody>"; - std::vector<std::string> blacklist = logic->get_blacklist(); + vector<string> blacklist = logic->get_blacklist(); for (i = blacklist.begin(); i != blacklist.end(); i++) resp << "<tr><td>" << (*i) << "</td></tr>"; resp << "</tbody></table>\n";