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