]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
add support for graphite/carbon to dnsdist, plus document it
authorbert hubert <bert.hubert@netherlabs.nl>
Fri, 8 May 2015 19:51:50 +0000 (21:51 +0200)
committerbert hubert <bert.hubert@netherlabs.nl>
Fri, 8 May 2015 19:51:50 +0000 (21:51 +0200)
pdns/Makefile.am
pdns/README-dnsdist.md
pdns/dnsdist-lua.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistconf.lua

index e126cb82e2322be2f43ba93c45d6b4d49db5e6c5..0e6ee5972e3afb6eb6956b9895d142aa0a274306 100644 (file)
@@ -565,6 +565,7 @@ dnsdist_SOURCES = \
        base32.cc \
        base64.hh \
        dnsdist.cc \
+       dnsdist-carbon.cc \
        dnsdist-lua.cc \
        dnsdist-tcp.cc \
        dnsdist-web.cc \
index e9d6724514b7a95dee7a26c6b3a3eba4bed440d8..a3c872c13ab9ed13960c75aa6f554c8657bfe0da 100644 (file)
@@ -412,6 +412,19 @@ fe80::/10
 ::/0
 ```
 
+Carbon/Graphite/Metronome
+-------------------------
+To emit metrics to Graphite, or any other software supporting the Carbon protocol, use:
+```
+carbonServer('ip-address-of-carbon-server', 'ourname', 30)
+```
+
+Where 'ourname' can be used to override your hostname, and '30' is the
+reporting interval in seconds.  The last two arguments can be omitted.  The
+latest version of [PowerDNS
+Metronome](https://github.com/ahupowerdns/metronome) comes with attractive
+graphs for dnsdist by default.
+
 All functions and types
 -----------------------
 Within `dnsdist` several core object types exist:
@@ -445,6 +458,8 @@ Here are all functions:
    * `showACL()`: show our ACL set
  * Blocking related:
    * `addDomainBlock(domain)`: block queries within this domain
+ * Carbon/Graphite/Metronome statistics related:
+   * `carbonServer(serverIP, [ourname], [interval])`: report statistics to serverIP using our hostname, or 'ourname' if provided, every 'interval' seconds
  * Control socket related:
    * `makeKey()`: generate a new server access key, emit configuration line ready for pasting
    * `setKey(key)`: set access key to that key. 
index 6d1c162c52e533b6e689813a1b4694b8d826cce3..b27d85f36cf667b31e8ae7e55ad8afbc16e0ca5b 100644 (file)
@@ -461,6 +461,19 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
   g_lua.registerFunction("add",(void (SuffixMatchNode::*)(const DNSName&)) &SuffixMatchNode::add);
   g_lua.registerFunction("check",(bool (SuffixMatchNode::*)(const DNSName&) const) &SuffixMatchNode::check);
 
+  g_lua.writeFunction("carbonServer", [](const std::string& address, boost::optional<string> ourName,
+                                        boost::optional<int> interval) {
+                       auto ours = g_carbon.getCopy();
+                       ours.server=ComboAddress(address, 2003);
+                       if(ourName)
+                         ours.ourname=*ourName;
+                       if(interval)
+                         ours.interval=*interval;
+                       if(!ours.interval)
+                         ours.interval=1;
+                       g_carbon.setState(ours);
+                     });
+
   g_lua.writeFunction("webserver", [client](const std::string& address, const std::string& password) {
       if(client)
        return;
index a11b9a1bbe14b93cf48c0446498753e3d52b610c..28a489b521fb4ee45805aaa533e92f50fbdf2fa5 100644 (file)
@@ -65,7 +65,6 @@ GlobalStateHolder<NetmaskGroup> g_ACL;
 string g_outputBuffer;
 vector<ComboAddress> g_locals;
 
-
 /* UDP: the grand design. Per socket we listen on for incoming queries there is one thread.
    Then we have a bunch of connected sockets for talking to downstream servers. 
    We send directly to those sockets.
@@ -161,6 +160,13 @@ void* responderThread(std::shared_ptr<DownstreamState> state)
       g_stats.servfailResponses++;
     state->latencyUsec = (127.0 * state->latencyUsec / 128.0) + udiff/128.0;
 
+    if(udiff < 1000) g_stats.latency0_1++;
+    else if(udiff < 10000) g_stats.latency1_10++;
+    else if(udiff < 50000) g_stats.latency10_50++;
+    else if(udiff < 100000) g_stats.latency50_100++;
+    else if(udiff < 1000000) g_stats.latency100_1000++;
+    else g_stats.latencySlow++;
+    
     g_stats.latency = (1023.0*g_stats.latency/1024.0) + udiff/1024.0;
 
     ids->origFD = -1;
@@ -1066,6 +1072,9 @@ try
     t1.detach();
   }
 
+  thread carbonthread(carbonDumpThread);
+  carbonthread.detach();
+
   thread stattid(maintThread);
   
   if(g_cmdLine.beDaemon || g_cmdLine.beSupervised) {
index 387f961b5e68731d6a3019ebe7f81db94becff4d..4c0840c1dc82f3d15d190d2362ab3bb347c9ea8f 100644 (file)
@@ -9,7 +9,7 @@
 #include <mutex>
 #include <thread>
 #include "sholder.hh"
-
+void* carbonDumpThread();
 struct DNSDistStats
 {
   using stat_t=std::atomic<uint64_t>; // aww yiss ;-)
@@ -25,8 +25,20 @@ struct DNSDistStats
   stat_t downstreamSendErrors{0};
   stat_t truncFail{0};
   stat_t noPolicy{0};
-  double latency{0};
+  stat_t latency0_1{0}, latency1_10{0}, latency10_50{0}, latency50_100{0}, latency100_1000{0}, latencySlow{0};
   
+  double latency{0};
+  std::vector<std::pair<std::string, stat_t*>> entries{
+    {"responses", &responses}, {"servfail-responses", &servfailResponses},
+    {"queries", &queries}, {"acl-drops", &aclDrops},
+    {"block-filter", &blockFilter}, {"rule-drop", &ruleDrop},
+    {"rule-nxdomain", &ruleNXDomain}, {"self-answered", &selfAnswered},
+    {"downstream-timeouts", &downstreamTimeouts}, {"downstream-send-errors", &downstreamSendErrors}, 
+    {"trunc-failures", &truncFail}, {"no-policy", &noPolicy},
+    {"latency0-1", &latency0_1}, {"latency1-10", &latency1_10},
+    {"latency10-50", &latency10_50}, {"latency50-100", &latency50_100}, 
+    {"latency100-1000", &latency100_1000}, {"latency-slow", &latencySlow}
+  };
 };
 
 extern struct DNSDistStats g_stats;
@@ -281,6 +293,14 @@ struct ServerPolicy
   policy_t policy;
 };
 
+struct CarbonConfig
+{
+  ComboAddress server{"0.0.0.0", 0};
+  std::string ourname;
+  unsigned int interval{30};
+};
+
+extern GlobalStateHolder<CarbonConfig> g_carbon;
 extern GlobalStateHolder<ServerPolicy> g_policy;
 extern GlobalStateHolder<servers_t> g_dstates;
 extern GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > > g_rulactions;
index ca45a22cd5f03802bf037b31d024cf9d45f6b535..cafe0a9d6f63b2c2ffa8162b86bcec7a71db827e 100644 (file)
@@ -3,6 +3,7 @@ webserver("0.0.0.0:8083", "geheim2")
 addLocal("0.0.0.0:5200")
 setKey("MXNeLFWHUe4363BBKrY06cAsH8NWNb+Se2eXU5+Bb74=")
 truncateTC(true) -- fix up possibly badly truncated answers from pdns 2.9.22
+carbonServer("2001:888:2000:1d::2")
 
 warnlog(string.format("Script starting %s", "up!"))
 
@@ -16,7 +17,7 @@ newServer("2001:4860:4860::8844",1)
 newServer("2620:0:ccc::2", 10) 
 newServer("2620:0:ccd::2", 10) 
 newServer{address="192.168.1.2", qps=1000, order=2}
-
+newServer{address="192.168.1.79:5300", order=2}
 newServer{address="127.0.0.1:5300", order=3}
 newServer{address="192.168.1.30:5300", pool="abuse"}