]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Make `topBandwidth()` behave like other top* functions 3730/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 18 Apr 2016 14:13:51 +0000 (16:13 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 18 Apr 2016 14:13:51 +0000 (16:13 +0200)
Fixes #3521.

pdns/dnsdist-lua2.cc
pdns/dnsdist-rings.cc
pdns/dnsdist.hh

index 18be93099a532810bcbdb8e1ea32e7d863a93e7d..2b5f42043291f0011679ba474c03c5e3aa62b608 100644 (file)
@@ -221,15 +221,11 @@ void moreLua(bool client)
     });
 
 
-  g_lua.writeFunction("topBandwidth", [](boost::optional<unsigned int> top_) {
+  g_lua.writeFunction("getTopBandwidth", [](unsigned int top) {
       setLuaNoSideEffect();
-      auto top = top_.get_value_or(10);
-      auto res = g_rings.getTopBandwidth(top);
-      boost::format fmt("%7d  %s\n");
-      for(const auto& l : res) {
-       g_outputBuffer += (fmt % l.first % l.second.toString()).str();
-      }
+      return g_rings.getTopBandwidth(top);
     });
+  g_lua.executeCode(R"(function topBandwidth(top) top = top or 10; for k,v in ipairs(getTopBandwidth(top)) do show(string.format("%4d  %-40s %4d %4.1f%%",k,v[1],v[2],v[3])) end end)");
 
   g_lua.writeFunction("delta", []() {
       setLuaNoSideEffect();
index 787260a663b5fa412848175f26682c2ccbbfccb4..0ae0ea124e22c526df54d783f0e92946171761a2 100644 (file)
@@ -4,36 +4,53 @@
 unsigned int Rings::numDistinctRequestors()
 {
   std::set<ComboAddress, ComboAddress::addressOnlyLessThan> s;
-  WriteLock wl(&queryLock);
+  ReadLock rl(&queryLock);
   for(const auto& q : queryRing)
     s.insert(q.requestor);
   return s.size();
 }
 
-vector<pair<unsigned int,ComboAddress> > Rings::getTopBandwidth(unsigned int numentries)
+std::unordered_map<int, vector<boost::variant<string,double>>> Rings::getTopBandwidth(unsigned int numentries)
 {
   map<ComboAddress, unsigned int, ComboAddress::addressOnlyLessThan> counts;
+  uint64_t total=0;
   {
-    WriteLock wl(&queryLock);
-    for(const auto& q : queryRing)
+    ReadLock rl(&queryLock);
+    for(const auto& q : queryRing) {
       counts[q.requestor]+=q.size;
+      total+=q.size;
+    }
   }
 
   {
     std::lock_guard<std::mutex> lock(respMutex);
-    for(const auto& r : respRing)
+    for(const auto& r : respRing) {
       counts[r.requestor]+=r.size;
+      total+=r.size;
+    }
   }
 
   typedef vector<pair<unsigned int, ComboAddress>> ret_t;
-  ret_t ret;
+  ret_t rcounts;
+  rcounts.reserve(counts.size());
   for(const auto& p : counts)
-    ret.push_back({p.second, p.first});
-  numentries = ret.size() < numentries ? ret.size() : numentries;
-  partial_sort(ret.begin(), ret.begin()+numentries, ret.end(), [](const ret_t::value_type&a, const ret_t::value_type&b)
+    rcounts.push_back({p.second, p.first});
+  numentries = rcounts.size() < numentries ? rcounts.size() : numentries;
+  partial_sort(rcounts.begin(), rcounts.begin()+numentries, rcounts.end(), [](const ret_t::value_type&a, const ret_t::value_type&b)
               {
-                return(b.second < a.second);
+                return(b.first < a.first);
               });
-  ret.resize(numentries);
+  std::unordered_map<int, vector<boost::variant<string,double>>> ret;
+  uint64_t rest = 0;
+  unsigned int count = 1;
+  for(const auto& rc : rcounts) {
+    if(count==numentries+1) {
+      rest+=rc.first;
+    }
+    else {
+      ret.insert({count++, {rc.second.toString(), rc.first, 100.0*rc.first/total}});
+    }
+  }
+  ret.insert({count, {"Rest", rest, total > 0 ? 100.0*rest/total : 100.0}});
   return ret;
 }
index 224f750f8bf31646edb69c0831c65f168b580954..a7893b38e57325c65a29c9aa2c8bddde3597d62f 100644 (file)
@@ -260,7 +260,7 @@ struct Rings {
   std::mutex respMutex;
   pthread_rwlock_t queryLock;
 
-  vector<pair<unsigned int, ComboAddress> > getTopBandwidth(unsigned int numentries);
+  std::unordered_map<int, vector<boost::variant<string,double> > > getTopBandwidth(unsigned int numentries);
   unsigned int numDistinctRequestors();
 };