]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
implement dynamic metric creation from Lua & code to rapidly update these metrics...
authorbert hubert <bert.hubert@netherlabs.nl>
Sun, 27 Dec 2015 21:21:55 +0000 (21:21 +0000)
committerbert hubert <bert.hubert@netherlabs.nl>
Sun, 27 Dec 2015 21:21:55 +0000 (21:21 +0000)
pdns/lua-recursor4.cc
pdns/misc.hh
pdns/powerdns-example-script.lua
pdns/rec_channel.hh
pdns/rec_channel_rec.cc

index 9895c4090be4060889017c7cf5b7fb3eb5cc8c87..12916218ab4f58cf3b91473e944a3ddaa7e6ab63 100644 (file)
@@ -4,7 +4,7 @@
 #include "dnsparser.hh"
 #include "syncres.hh"
 #include "namespaces.hh"
-
+#include "rec_channel.hh" 
 #if !defined(HAVE_LUA)
 
 RecursorLua4::RecursorLua4(const std::string &fname)
@@ -154,7 +154,16 @@ void RecursorLua4::DNSQuestion::addAnswer(uint16_t type, const std::string& cont
 {
   addRecord(type, content, DNSResourceRecord::ANSWER, ttl, name);
 }
-  
+
+struct DynMetric
+{
+  std::atomic<unsigned long>* ptr;
+  void inc() { (*ptr)++; }
+  void incBy(unsigned int by) { (*ptr)+= by; }
+  unsigned long get() { return *ptr; }
+  void set(unsigned long val) { *ptr =val; }
+};
+
 RecursorLua4::RecursorLua4(const std::string& fname)
 {
   d_lw = new LuaContext;
@@ -241,6 +250,16 @@ RecursorLua4::RecursorLua4(const std::string& fname)
   for(const auto& n : QType::names)
     pd.push_back({n.first, n.second});
   d_lw->writeVariable("pdns", pd);
+
+  d_lw->writeFunction("getMetric", [](const std::string& str) {
+      return DynMetric{getDynMetric(str)};
+    });
+
+  d_lw->registerFunction("inc", &DynMetric::inc);
+  d_lw->registerFunction("incBy", &DynMetric::incBy);
+  d_lw->registerFunction("set", &DynMetric::set);
+  d_lw->registerFunction("get", &DynMetric::get);
+  
   
   ifstream ifs(fname);
   if(!ifs) {
index 260ee7c36f53dfc5bb81409e8185050b8a4ab31b..4ba73f92a9f9359dcf8485d4d1e840290696e342 100644 (file)
@@ -1,6 +1,6 @@
 /*
     PowerDNS Versatile Database Driven Nameserver
-    Copyright (C) 2002-2012  PowerDNS.COM BV
+    Copyright (C) 2002-2015  PowerDNS.COM BV
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License version 2
index 96825c9ffc3ba1455b971bb28907bc30e79685a7..8177b0ab34b31b60af38dc73a53aeab165f765aa 100644 (file)
@@ -11,15 +11,25 @@ malwareset:add("nl")
 
 magic2 = newDN("www.magic2.com")
 
+
+magicMetric = getMetric("magic")
+
 -- shows the various ways of blocking, dropping, changing questions
 -- return false to say you did not take over the question, but we'll still listen to 'variable'
 -- to selectively disable the cache
 function preresolve(dq)
        print("Got question for "..dq.qname:toString().." from "..dq.remoteaddr:toString().." to "..dq.localaddr:toString())
 
+       loc = newCA("127.0.0.1")
+       if(dq.remoteaddr:equal(loc))
+       then
+               print("Query from loopback")
+       end
+
        -- note that the comparisons below are CaSe InSensiTivE and you don't have to worry about trailing dots
        if(dq.qname:equal("magic.com"))
        then
+               magicMetric:inc()
                print("Magic!")
        else
                print("not magic..")
@@ -78,7 +88,7 @@ end
 
 
 badips = newNMG()
-badips:addMask("127.0.0.0/8")
+badips:addMask("127.1.0.0/16")
 
 -- this check is applied before any packet parsing is done
 function ipfilter(loc, rem)
index 94f4ae82a2190d495d007fa928e511e5208a64df..c5b62fb10b510557258b0f44610229b9737398d4 100644 (file)
@@ -50,4 +50,5 @@ std::vector<ComboAddress>* pleaseGetRemotes();
 std::vector<ComboAddress>* pleaseGetServfailRemotes();
 std::vector<ComboAddress>* pleaseGetLargeAnswerRemotes();
 DNSName getRegisteredName(const DNSName& dom);
+std::atomic<unsigned long>* getDynMetric(const std::string& str);
 #endif 
index 3123a49358da4969004ad3676cb2308771bd7b2d..15a33ab9a8696f1c5dfba2f9834d5f86c7c0d4e1 100644 (file)
@@ -37,7 +37,8 @@ pthread_mutex_t g_carbon_config_lock=PTHREAD_MUTEX_INITIALIZER;
 map<string, const uint32_t*> d_get32bitpointers;
 map<string, const uint64_t*> d_get64bitpointers;
 map<string, function< uint32_t() > >  d_get32bitmembers;
-
+pthread_mutex_t d_dynmetricslock = PTHREAD_MUTEX_INITIALIZER;
+map<string, std::atomic<unsigned long>* > d_dynmetrics;
 void addGetStat(const string& name, const uint32_t* place)
 {
   d_get32bitpointers[name]=place;
@@ -51,6 +52,18 @@ void addGetStat(const string& name, function<uint32_t ()> f )
   d_get32bitmembers[name]=f;
 }
 
+std::atomic<unsigned long>* getDynMetric(const std::string& str)
+{
+  Lock l(&d_dynmetricslock);
+  auto f = d_dynmetrics.find(str);
+  if(f != d_dynmetrics.end())
+    return f->second;
+
+  auto ret = new std::atomic<unsigned long>();
+  d_dynmetrics[str]= ret;
+  return ret;
+}
+
 optional<uint64_t> get(const string& name) 
 {
   optional<uint64_t> ret;
@@ -62,6 +75,11 @@ optional<uint64_t> get(const string& name)
   if(d_get32bitmembers.count(name))
     return d_get32bitmembers.find(name)->second();
 
+  Lock l(&d_dynmetricslock);
+  auto f =rplookup(d_dynmetrics, name);
+  if(f)
+    return (*f)->load();
+  
   return ret;
 }
 
@@ -80,6 +98,9 @@ map<string,string> getAllStatsMap()
       continue; // too slow for 'get-all'
     ret.insert(make_pair(the32bitmembers.first, std::to_string(the32bitmembers.second())));
   }
+  Lock l(&d_dynmetricslock);
+  for(const auto& a : d_dynmetrics)
+    ret.insert({a.first, std::to_string(*a.second)});
   return ret;
 }