From: bert hubert Date: Mon, 4 Jan 2016 14:44:55 +0000 (+0100) Subject: make grepq support multiple criteria, document this, document topSlow(), fix topSlow... X-Git-Tag: dnsdist-1.0.0-alpha2~127^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2a05b4a9007cf30b96af706f8b49e4013919a66b;p=pdns make grepq support multiple criteria, document this, document topSlow(), fix topSlow() label grouping --- diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index 348446895..5b520ea50 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -424,8 +424,10 @@ This is still much in flux, but for now, try: * `topQueries(20)`: shows the top-20 queries * `topQueries(20,2)`: shows the top-20 two-level domain queries (so `topQueries(20,1)` only shows TLDs) * `topResponses(20, 2)`: top-20 servfail responses (use ,3 for NXDOMAIN) - * `grepq(Netmask|DNS Name [, n])`: shows the queries and responses matching the specified client address or range (Netmask), or the specified DNS Name - * `topBandwidth(top)`: get top-`top` clients that consume the most bandwidth over length of ringbuffer + * `grepq(Netmask|DNS Name|100ms [, n])`: shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms + * `grepq({"::1", "powerdns.com", "100ms"} [, n])`: shows the last n queries and responses matching the specified client address AND range (Netmask) AND the specified DNS Name AND slower than 100ms + * `topBandwidth(top)`: show top-`top` clients that consume the most bandwidth over length of ringbuffer + * `topSlow([top][, limit][, labels])`: show `top` queries slower than `limit` milliseconds, grouped by last `labels` labels For example: ``` diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index daae17104..b2d9111fa 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -977,7 +977,7 @@ vector> setupLua(bool client, const std::string& confi }); - g_lua.executeCode(R"(function topSlow(top, msec, labels) top = top or 10; msec = msec or 500; for k,v in ipairs(getSlowResponses(top, msec)) do show(string.format("%4d %-40s %4d %4.1f%%",k,v[1],v[2],v[3])) end end)"); + g_lua.executeCode(R"(function topSlow(top, msec, labels) top = top or 10; msec = msec or 500; for k,v in ipairs(getSlowResponses(top, msec, labels)) do show(string.format("%4d %-40s %4d %4.1f%%",k,v[1],v[2],v[3])) end end)"); g_lua.writeFunction("showResponseLatency", []() { diff --git a/pdns/dnsdist-lua2.cc b/pdns/dnsdist-lua2.cc index 7d2b848c9..308f362d9 100644 --- a/pdns/dnsdist-lua2.cc +++ b/pdns/dnsdist-lua2.cc @@ -230,25 +230,38 @@ void moreLua() } }); - g_lua.writeFunction("grepq", [](const std::string& s, boost::optional limit) { + g_lua.writeFunction("grepq", [](boost::variant > > inp, boost::optional limit) { boost::optional nm; boost::optional dn; - unsigned int msec=0; - try - { - nm = Netmask(s); + int msec=-1; + + vector vec; + auto str=boost::get(&inp); + if(str) + vec.push_back(*str); + else { + auto v = boost::get > >(inp); + for(const auto& a: v) + vec.push_back(a.second); } - catch(...) { - if(boost::ends_with(s,"ms") && sscanf(s.c_str(), "%ums", &msec)) { - ; - } - else { - try { dn=DNSName(s); } - catch(...) - { - g_outputBuffer = "Could not parse '"+s+"' as domain name or netmask"; - return; - } + + for(const auto& s : vec) { + try + { + nm = Netmask(s); + } + catch(...) { + if(boost::ends_with(s,"ms") && sscanf(s.c_str(), "%ums", &msec)) { + ; + } + else { + try { dn=DNSName(s); } + catch(...) + { + g_outputBuffer = "Could not parse '"+s+"' as domain name or netmask"; + return; + } + } } } @@ -276,16 +289,23 @@ void moreLua() std::multimap out; - boost::format fmt("%-7.1f %-47s %-12s %-5d %-25s %-5s %-4.1f %-2s %-2s %-2s %s\n"); + boost::format fmt("%-7.1f %-47s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %s\n"); g_outputBuffer+= (fmt % "Time" % "Client" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str(); - for(const auto& c : qr) { - if((nm && nm->match(c.requestor)) || (dn && c.name.isPartOf(*dn)) ) { - QType qt(c.qtype); - out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % "" % htons(c.dh.id) % c.name.toString() % qt.getName() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % "Question").str() )) ; - - if(limit && *limit==++num) - break; + if(msec==-1) { + for(const auto& c : qr) { + bool nmmatch=true, dnmatch=true; + if(nm) + nmmatch = nm->match(c.requestor); + if(dn) + dnmatch = c.name.isPartOf(*dn); + if(nmmatch && dnmatch) { + QType qt(c.qtype); + out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % "" % htons(c.dh.id) % c.name.toString() % qt.getName() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % "Question").str() )) ; + + if(limit && *limit==++num) + break; + } } } num=0; @@ -293,7 +313,15 @@ void moreLua() string extra; for(const auto& c : rr) { - if((nm && nm->match(c.requestor)) || (dn && c.name.isPartOf(*dn)) || (msec && (c.usec/1000 > msec)) ) { + bool nmmatch=true, dnmatch=true, msecmatch=true; + if(nm) + nmmatch = nm->match(c.requestor); + if(dn) + dnmatch = c.name.isPartOf(*dn); + if(msec != -1) + msecmatch=(c.usec/1000 > (unsigned int)msec); + + if(nmmatch && dnmatch && msecmatch) { QType qt(c.qtype); if(!c.dh.rcode) extra=". " +std::to_string(htons(c.dh.ancount))+ " answers";