1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
#include "webinterface"
#include "balancer/balancer"
void Webinterface::answer_status() {
string xml =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<?xml-stylesheet type=\"text/xsl\" href=\"/xslt\"?>\n"
"<status>\n";
ostringstream o;
o <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<?xml-stylesheet type=\"text/xsl\" href=\"/xslt\"?>\n"
"<status>\n"
" <id>\n"
" <version>" << VER << "</version>\n"
" <distsite>" << DISTSITE << "</distsite>\n"
" </id>\n"
" <server>\n"
" <address>" << config.sipaddr() << ":" << config.sport() << "</address>\n"
" <type>" << config.stypestr() << "</type>\n"
" <clientreadtimeout>" << config.client_read_timeout() << "</clientreadtimeout>\n"
" <clientwritetimeout>" << config.client_write_timeout() << "</clientwritetimeout>\n"
" <backendreadtimeout>" << config.backend_read_timeout() << "</backendreadtimeout>\n"
" <backendwritetimeout>" << config.backend_write_timeout() << "</backendwritetimeout>\n"
" <dispatchmode>" << config.dispatchmodestr() << "</dispatchmode>\n"
" <removereservations>" << config.removereservations() << "</removereservations>\n"
" <webinterface>" << config.webinterfaceip() << ':' << config.webinterfaceport() << "</webinterface>\n"
" <dnscachetimeout>" << config.dnscachetimeout() << "</dnscachetimeout>\n"
" <buffersize>" << config.buffersize() << "</buffersize>\n"
" <closesocketsfast>" << config.fastclose() << "</closesocketsfast>\n"
" <onstart>" << config.onstart() << "</onstart>\n"
" <onend>" << config.onend() << "</onend>\n"
" <onfail>" << config.onfail() << "</onfail>\n"
" <checks>\n"
" <wakeupinterval>" << config.wakeupsec() << "</wakeupinterval>\n"
" <checkupinterval>" << config.checkupsec() << "</checkupinterval>\n"
" </checks>\n"
" <debugging>\n"
" <verbose>" << config.verbose() << "</verbose>\n"
" <debug>" << config.debug() << "</debug>\n"
" <logtrafficdir>" << config.dumpdir() << "</logtrafficdir>\n"
" </debugging>\n"
" <dosprotection>\n"
" <maxconnections>" << config.maxconn() << "</maxconnections>\n"
" <timeinterval>" << config.connrate_time() << "</timeinterval>\n"
" <hardmaxconnrate>" << config.hardmaxconnrate() << "</hardmaxconnrate>\n"
" <softmaxconnrate>" << config.softmaxconnrate() << "</softmaxconnrate>\n"
" <defertime>" << config.defertime() << "</defertime>\n"
" <hardmaxconnexcess>" << config.hardmaxconnexcess() << "</hardmaxconnexcess>\n"
" <softmaxconnexcess>" << config.softmaxconnexcess() << "</softmaxconnexcess>\n"
" </dosprotection>\n"
" <acl>\n"
" <allow>\n";
for (unsigned i = 0; i < config.nallow(); i++)
o <<
" <allowfrom>\n"
" <nr>" << i << "</nr>\n"
" <mask>" << inet_ntoa(config.allow(i)) << "</mask>\n"
" </allowfrom>\n";
o <<
" </allow>\n"
" <deny>\n";
for (unsigned i = 0; i < config.ndeny(); i++)
o <<
" <denyfrom>\n"
" <nr>" << i << "</nr>\n"
" <mask>" << inet_ntoa(config.deny(i)) << "</mask>\n"
" </denyfrom>\n";
o <<
" </deny>\n"
" </acl>\n"
" <http>\n"
" <addxrversion>" << config.addxrversion() << "</addxrversion>\n"
" <addxforwardedfor>" << config.addxforwardedfor() << "</addxforwardedfor>\n"
" <stickyhttp>" << config.stickyhttp() << "</stickyhttp>\n"
" <replacehostheader>" << config.replacehostheader() << "</replacehostheader>\n"
" <serverheaders>\n"
;
for (unsigned i = 0; i < config.nserverheaders(); i++)
o <<
" <serverheader>\n"
" <nr>" << i << "</nr>\n"
" <header>" << config.serverheader(i) << "</header>\n"
" </serverheader>\n"
;
o <<
" </serverheaders>\n"
" </http>\n"
" <backends>" << balancer.nbackends() << "</backends>\n"
" <terminating>" << balancer.terminate() << "</terminating>\n"
" <connections>" << balancer.connections() << "</connections>\n"
" </server>\n"
;
for (unsigned i = 0; i < balancer.nbackends(); i++)
o <<
" <backend>\n"
" <nr>" << i << "</nr>\n"
" <address>" << balancer.backend(i).description() << "</address>\n"
" <weight>" << balancer.backend(i).weight() << "</weight>\n"
" <maxconnections>" << balancer.backend(i).maxconn() << "</maxconnections>\n"
" <loadavg>" << balancer.backend(i).loadavg() << "</loadavg>\n"
" <up>" << balancer.backend(i).upstr() << "</up>\n"
" <live>" << balancer.backend(i).livestr() << "</live>\n"
" <available>" << balancer.backend(i).availablestr() << "</available>\n"
" <connections>" << balancer.backend(i).connections() << "</connections>\n"
" <connecterrors>" << balancer.backend(i).connecterrors() << "</connecterrors>\n"
" <bytesserved>" << balancer.backend(i).bytesserved() << "</bytesserved>\n"
" <clientsserved>" << balancer.backend(i).clientsserved() << "</clientsserved>\n"
" <hostmatch>" << balancer.backend(i).hostmatch() << "</hostmatch>\n"
" <urlmatch>" << balancer.backend(i).urlmatch() << "</urlmatch>\n"
" <backendcheck>" << balancer.backend(i).backendcheck().setting() << "</backendcheck>\n"
" </backend>\n"
;
o <<
" <activity>\n"
" <threadlist>\n";
unsigned nthreads = 0, max_open_files;
struct rlimit rl;
if (getrlimit(RLIMIT_NOFILE, &rl))
throw Error("Failed to get limit for open files");
max_open_files = unsigned(rl.rlim_cur);
for (Threadmap::iterator it = Threadlist::map().begin();
it != Threadlist::map().end();
it++) {
nthreads++;
pthread_t thread_id = (*it).first;
Threadinfo thread_info = (*it).second;
o <<
" <thread>\n"
" <id>" << thread_id << "</id>\n"
" <description>" << thread_info.desc() << "</description>\n"
" <backend>" << thread_info.backend() << "</backend>\n"
" <address>";
if (thread_info.backend() >= 0)
o << balancer.backend(thread_info.backend()).description();
o <<
"</address>\n"
" <duration>" << thread_info.timestamp().elapsed() << "</duration>\n"
" <clientip>" << inet_ntoa(thread_info.clientip()) << "</clientip>\n"
" </thread>\n";
}
/* The estimate of the number of used fd's is:
* Base is 5 (stdin/stdout/stderr, listen-fd for service, listen-fd
* for webinterface
* Plus 2 x #-threads (1 to client, 1 to backend)
* There will be fd's in use for shared libs etc., but we don't see
* those..
*/
o <<
" </threadlist>\n"
" <threadcount>" << nthreads << "</threadcount>\n"
" <openfiles>" << nthreads * 2 + 5 << "</openfiles>\n"
" <maxopenfiles>" << max_open_files << "</maxopenfiles>\n"
" </activity>\n";
o <<
"</status>\n\n";
answer_blob (o.str());
}
|