]> granicus.if.org Git - pdns/commitdiff
make grepq support multiple criteria, document this, document topSlow(), fix topSlow...
authorbert hubert <bert.hubert@powerdns.com>
Mon, 4 Jan 2016 14:44:55 +0000 (15:44 +0100)
committerbert hubert <bert.hubert@powerdns.com>
Mon, 4 Jan 2016 14:44:55 +0000 (15:44 +0100)
pdns/README-dnsdist.md
pdns/dnsdist-lua.cc
pdns/dnsdist-lua2.cc

index 348446895a56bc38cfd5530e26ca66cb3cd8f18e..5b520ea507df1872bb34c4b310724904698e77ee 100644 (file)
@@ -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:
 ```
index daae1710404166cf64c3dd8e1d1947455085c16b..b2d9111fa15e54c1fd9779bbf3b17ee6368f37c2 100644 (file)
@@ -977,7 +977,7 @@ vector<std::function<void(void)>> 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", []() {
index 7d2b848c90b4af363f3ad46d064215070c25ac8f..308f362d980dc2f7b1325f31ca96da34d5387e7f 100644 (file)
@@ -230,25 +230,38 @@ void moreLua()
       }
     });
 
-  g_lua.writeFunction("grepq", [](const std::string& s, boost::optional<unsigned int> limit) {
+  g_lua.writeFunction("grepq", [](boost::variant<string, vector<pair<int,string> > > inp, boost::optional<unsigned int> limit) {
       boost::optional<Netmask>  nm;
       boost::optional<DNSName> dn;
-      unsigned int msec=0;
-      try 
-      {
-        nm = Netmask(s);
+      int msec=-1;
+
+      vector<string> vec;
+      auto str=boost::get<string>(&inp);
+      if(str)
+        vec.push_back(*str);
+      else {
+        auto v = boost::get<vector<pair<int, string> > >(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<struct timespec, string> 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";