]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/ws.cc
fix up printing of %eth0 scope in ComboAddress::toStringWithPort
[thirdparty/pdns.git] / pdns / ws.cc
CommitLineData
12c86877 1/*
64e8f298 2 Copyright (C) 2002 - 2007 PowerDNS.COM BV
12c86877
BH
3
4 This program is free software; you can redistribute it and/or modify
9054d8a4
BH
5 it under the terms of the GNU General Public License version 2
6 as published by the Free Software Foundation
12c86877
BH
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
06bd9ccf 15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9054d8a4
BH
16*/
17#include "utility.hh"
12c86877
BH
18#include "ws.hh"
19#include "webserver.hh"
20#include "logger.hh"
21#include "statbag.hh"
22#include "misc.hh"
23#include "arguments.hh"
24#include "dns.hh"
dcc65f25 25#include <boost/format.hpp>
12c86877
BH
26
27extern StatBag S;
28
29StatWebServer::StatWebServer()
30{
31 d_start=time(0);
96d299db
BH
32 d_min10=d_min5=d_min1=0;
33 d_ws = new WebServer(arg()["webserver-address"], arg().asNum("webserver-port"),arg()["webserver-password"]);
12c86877
BH
34}
35
36void StatWebServer::go()
37{
38 S.doRings();
39 pthread_create(&d_tid, 0, threadHelper, this);
40 pthread_create(&d_tid, 0, statThreadHelper, this);
41}
42
12c86877
BH
43void StatWebServer::statThread()
44{
45 try {
46 for(;;) {
47 d_queries.submit(S.read("udp-queries"));
48 d_cachehits.submit(S.read("packetcache-hit"));
49 d_cachemisses.submit(S.read("packetcache-miss"));
50 d_qcachehits.submit(S.read("query-cache-hit"));
51 d_qcachemisses.submit(S.read("query-cache-miss"));
52 Utility::sleep(1);
53 }
54 }
55 catch(...) {
56 L<<Logger::Error<<"Webserver statThread caught an exception, dying"<<endl;
57 exit(1);
58 }
59}
60
61void *StatWebServer::statThreadHelper(void *p)
62{
63 StatWebServer *sws=static_cast<StatWebServer *>(p);
64 sws->statThread();
65 return 0; // never reached
66}
67
68
69void *StatWebServer::threadHelper(void *p)
70{
71 StatWebServer *sws=static_cast<StatWebServer *>(p);
72 sws->launch();
73 return 0; // never reached
74}
75
76void printtable(ostringstream &ret, const string &ringname, const string &title, int limit=10)
77{
78 int tot=0;
79 int entries=0;
80 vector<pair <string,int> >ring=S.getRing(ringname);
81
82 for(vector<pair<string,int> >::const_iterator i=ring.begin(); i!=ring.end();++i) {
83 tot+=i->second;
84 entries++;
85 }
86
87
88 ret<<"<table border=1><tr><td colspan=3 bgcolor=#0000ff>"
89 "<a href=?ring="<<ringname<<"><font color=#ffffff>Top-"<<limit<<" of ";
90 ret<<entries<<": "<<title<<"</a></td>"<<endl;
91
92 ret<<"<tr><td colspan=3><table bgcolor=#ff0000 width=100%><tr><td align=left>"
93 "<a href=?resetring="<<ringname<<"><font color=#ffffff>Reset</a></td>";
94 ret<<"<td align=right>Resize: ";
95
96 int sizes[]={10,100,500,1000,10000,500000,0};
97 for(int i=0;sizes[i];++i) {
98 if(S.getRingSize(ringname)!=sizes[i])
99 ret<<"<a href=?resizering="<<ringname<<"&size="<<sizes[i]<<">"<<sizes[i]<<"</a> ";
100 else
101 ret<<"("<<sizes[i]<<") ";
102 }
103 ret<<"</td></table>"<<endl;
104
105
106 int printed=0;
107 for(vector<pair<string,int> >::const_iterator i=ring.begin();limit && i!=ring.end();++i,--limit) {
b6f57093 108 ret<<"<tr><td>"<<i->first<<"</td><td>"<<i->second<<"</td><td align=right>"<< StatWebServer::makePercentage(i->second*100.0/tot)<<"</td>"<<endl;
12c86877
BH
109 printed+=i->second;
110 }
111 ret<<"<tr><td colspan=3></td></tr>"<<endl;
112 if(printed!=tot)
b6f57093 113 ret<<"<tr><td><b>Rest:</b></td><td><b>"<<tot-printed<<"</b></td><td align=right><b>"<< StatWebServer::makePercentage((tot-printed)*100.0/tot)<<"</b></td>"<<endl;
12c86877
BH
114
115 ret<<"<tr><td><b>Total:</b></td><td><b>"<<tot<<"</td><td align=right><b>100%</b></td>";
116 ret<<"</table><p>"<<endl;
117}
118
119void StatWebServer::printvars(ostringstream &ret)
120{
121 ret<<"<table border=1><tr><td colspan=3 bgcolor=#0000ff><font color=#ffffff>Variables</td>"<<endl;
122
123
124 vector<string>entries=S.getEntries();
125 for(vector<string>::const_iterator i=entries.begin();i!=entries.end();++i) {
126 ret<<"<tr><td>"<<*i<<"</td><td>"<<S.read(*i)<<"</td><td>"<<S.getDescrip(*i)<<"</td>"<<endl;
127 }
128}
129
130void StatWebServer::printargs(ostringstream &ret)
131{
132 ret<<"<table border=1><tr><td colspan=3 bgcolor=#0000ff><font color=#ffffff>Arguments</td>"<<endl;
133
134 vector<string>entries=arg().list();
135 for(vector<string>::const_iterator i=entries.begin();i!=entries.end();++i) {
136 ret<<"<tr><td>"<<*i<<"</td><td>"<<arg()[*i]<<"</td><td>"<<arg().getHelp(*i)<<"</td>"<<endl;
137 }
138}
139
b6f57093
BH
140string StatWebServer::makePercentage(const double& val)
141{
142 return (boost::format("%.01f%%") % val).str();
143}
144
12c86877
BH
145string StatWebServer::indexfunction(const map<string,string> &varmap, void *ptr, bool *custom)
146{
147
148 StatWebServer *sws=static_cast<StatWebServer *>(ptr);
149 map<string,string>rvarmap=varmap;
150 if(!rvarmap["resetring"].empty()){
151 *custom=true;
152 S.resetRing(rvarmap["resetring"]);
153 return "HTTP/1.1 301 Moved Permanently\nLocation: /\nConnection: close\n\n";
154 }
155 if(!rvarmap["resizering"].empty()){
156 *custom=true;
157 S.resizeRing(rvarmap["resizering"], atoi(rvarmap["size"].c_str()));
158 return "HTTP/1.1 301 Moved Permanently\nLocation: /\nConnection: close\n\n";
159 }
160
161 ostringstream ret;
162
163 ret<<"<html><head><title>PowerDNS Operational Monitor</title></head><body bgcolor=#ffffff>"<<endl;
164
165
caa6eefa
BH
166 ret<<"<h2>";
167 if(!arg()["config-name"].empty())
168 ret<<"["<<arg()["config-name"]<<"]";
12c86877 169 if(rvarmap["ring"].empty())
caa6eefa 170 ret<<"PDNS "VERSION" Main Page</h2>"<<endl;
12c86877 171 else
caa6eefa 172 ret<<"Details page</h2><a href=/>Back to main page</a><p>"<<endl;
12c86877
BH
173
174 time_t passed=time(0)-s_starttime;
175
176 ret<<"Uptime: ";
177 ret<<humanDuration(passed)<<endl;
178
179
395b07ea 180 ret<<"Queries/second, 1, 5, 10 minute averages: "<<std::setprecision(3)<<
12c86877
BH
181 sws->d_queries.get1()<<", "<<
182 sws->d_queries.get5()<<", "<<
183 sws->d_queries.get10()<<". Max queries/second: "<<sws->d_queries.getMax()<<
184 "<br>"<<endl;
185
186 if(sws->d_cachemisses.get10()+sws->d_cachehits.get10()>0)
b6f57093
BH
187 ret<<"Cache hitrate, 1, 5, 10 minute averages: "<<
188 makePercentage((sws->d_cachehits.get1()*100.0)/((sws->d_cachehits.get1())+(sws->d_cachemisses.get1())))<<", "<<
189 makePercentage((sws->d_cachehits.get5()*100.0)/((sws->d_cachehits.get5())+(sws->d_cachemisses.get5())))<<", "<<
190 makePercentage((sws->d_cachehits.get10()*100.0)/((sws->d_cachehits.get10())+(sws->d_cachemisses.get10())))<<
191 "<br>"<<endl;
12c86877
BH
192
193 if(sws->d_qcachemisses.get10()+sws->d_qcachehits.get10()>0)
395b07ea 194 ret<<"Backend query cache hitrate, 1, 5, 10 minute averages: "<<std::setprecision(2)<<
b6f57093
BH
195 makePercentage((sws->d_qcachehits.get1()*100.0)/((sws->d_qcachehits.get1())+(sws->d_qcachemisses.get1())))<<", "<<
196 makePercentage((sws->d_qcachehits.get5()*100.0)/((sws->d_qcachehits.get5())+(sws->d_qcachemisses.get5())))<<", "<<
197 makePercentage((sws->d_qcachehits.get10()*100.0)/((sws->d_qcachehits.get10())+(sws->d_qcachemisses.get10())))<<
198 "<br>"<<endl;
12c86877 199
395b07ea 200 ret<<"Backend query load, 1, 5, 10 minute averages: "<<std::setprecision(3)<<
12c86877
BH
201 sws->d_qcachemisses.get1()<<", "<<
202 sws->d_qcachemisses.get5()<<", "<<
203 sws->d_qcachemisses.get10()<<". Max queries/second: "<<sws->d_qcachemisses.getMax()<<
204 "<br>"<<endl;
205
206 ret<<"Total queries: "<<S.read("udp-queries")<<". Question/answer latency: "<<S.read("latency")/1000.0<<"ms<p>"<<endl;
207 if(rvarmap["ring"].empty()) {
208 vector<string>entries=S.listRings();
209 for(vector<string>::const_iterator i=entries.begin();i!=entries.end();++i)
210 printtable(ret,*i,S.getRingTitle(*i));
211
212 sws->printvars(ret);
213 if(arg().mustDo("webserver-print-arguments"))
214 sws->printargs(ret);
215 }
216 else
217 printtable(ret,rvarmap["ring"],S.getRingTitle(rvarmap["ring"]),100);
218
219 ret<<"</body></html>"<<endl;
220
221 return ret.str();
222}
223
224void StatWebServer::launch()
225{
226 try {
96d299db
BH
227
228 d_ws->setCaller(this);
229 d_ws->registerHandler("",&indexfunction);
230 d_ws->go();
12c86877
BH
231 }
232 catch(...) {
233 L<<Logger::Error<<"StatWebserver thread caught an exception, dying"<<endl;
234 exit(1);
235 }
236}