]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add statistics command for remote logging stats
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 29 Aug 2022 12:51:38 +0000 (14:51 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 28 Sep 2022 09:28:05 +0000 (11:28 +0200)
pdns/fstrm_logger.hh
pdns/rec_channel_rec.cc
pdns/recursordist/rec-main.cc
pdns/recursordist/rec-main.hh
pdns/remote_logger.hh

index c9890fc52d854bd71e5a353602b302231e624a33..2b1d69036b00491c5f9144ecfb41077932e85864 100644 (file)
@@ -39,6 +39,12 @@ public:
   FrameStreamLogger(int family, const std::string& address, bool connect, const std::unordered_map<string,unsigned>& options = std::unordered_map<string,unsigned>());
   ~FrameStreamLogger();
   [[nodiscard]] RemoteLoggerInterface::Result queueData(const std::string& data) override;
+
+  std::string address() const override
+  {
+    return d_address;
+  }
+
   const std::string name() const override
   {
     return "dnstap";
index 09b5854159b03cc54481c33a52d5e648205b31aa..8b4bd6292f95f6cf1acd35fe13b2b651740b9641 100644 (file)
@@ -939,6 +939,18 @@ static ProxyMappingStats_t* pleaseGetProxyMappingStats()
   return ret;
 }
 
+static RemoteLoggerStats_t* pleaseGetRemoteLoggerStats()
+{
+  auto ret = new RemoteLoggerStats_t;
+
+  if (t_protobufServers) {
+    for (const auto& s : *t_protobufServers) {
+      ret->emplace(std::make_pair(s->address(), s->getStats()));
+    }
+  }
+  return ret;
+}
+
 static string doGetProxyMappingStats()
 {
   ostringstream ret;
@@ -950,6 +962,54 @@ static string doGetProxyMappingStats()
   return ret.str();
 }
 
+static RemoteLoggerStats_t* pleaseGetOutgoingRemoteLoggerStats()
+{
+  auto ret = new RemoteLoggerStats_t;
+
+  if (t_outgoingProtobufServers) {
+    for (const auto& s : *t_outgoingProtobufServers) {
+      ret->emplace(std::make_pair(s->address(), s->getStats()));
+    }
+  }
+  return ret;
+}
+
+static RemoteLoggerStats_t* pleaseGetFramestreamLoggerStats()
+{
+  auto ret = new RemoteLoggerStats_t;
+
+  if (t_frameStreamServersInfo.servers) {
+    for (const auto& s : *t_frameStreamServersInfo.servers) {
+      ret->emplace(std::make_pair(s->address(), s->getStats()));
+    }
+  }
+  return ret;
+}
+
+static void remoteLoggerStats(const string& name, const RemoteLoggerStats_t& stats, ostringstream& os)
+{
+  if (stats.size() > 0) {
+    std::string filler(name.size(), ' ');
+    os << name << "\tQueued\tPipe-\tToo-\tOther-\tAddress" << endl;
+    os << filler << "\t\tFull\tLarge\terror" << endl;
+    for (const auto& [key, entry]: stats) {
+      os << filler<< '\t' << entry.d_queued << '\t' << entry.d_pipeFull << '\t' << entry.d_tooLarge << '\t' << entry.d_otherError << '\t' << key << endl;
+    }
+  }
+}
+
+static string getRemoteLoggerStats()
+{
+  ostringstream os;
+  auto stats = broadcastAccFunction<RemoteLoggerStats_t>(pleaseGetRemoteLoggerStats);
+  remoteLoggerStats("Protobuf   ", stats, os);
+  stats = broadcastAccFunction<RemoteLoggerStats_t>(pleaseGetOutgoingRemoteLoggerStats);
+  remoteLoggerStats("OutProtobuf", stats, os);
+  stats = broadcastAccFunction<RemoteLoggerStats_t>(pleaseGetFramestreamLoggerStats);
+  remoteLoggerStats("Framestream", stats, os);
+  return os.str();
+}
+
 static uint64_t calculateUptime()
 {
   return time(nullptr) - g_stats.startupTime;
@@ -1994,6 +2054,7 @@ RecursorControlChannel::Answer RecursorControlParser::getAnswer(int s, const str
             "get-parameter [key1] [key2] ..   get configuration parameters\n"
             "get-proxymapping-stats           get proxy mapping statistics\n"
             "get-qtypelist                    get QType statistics\n"
+            "get-remotelogger-stats           get remote logger statistics\n"
             "                                 notice: queries from cache aren't being counted yet\n"
             "hash-password [work-factor]      ask for a password then return the hashed version\n"
             "help                             get this list\n"
@@ -2248,6 +2309,9 @@ RecursorControlChannel::Answer RecursorControlParser::getAnswer(int s, const str
   if (cmd == "get-proxymapping-stats") {
     return {0, doGetProxyMappingStats()};
   }
+  if (cmd == "get-remotelogger-stats") {
+    return {0, getRemoteLoggerStats() };
+  }
 
   return {1, "Unknown command '" + cmd + "', try 'help'\n"};
 }
index 42eea037bb8dcb5b68da697afad56efc1b9e37b5..90f8b0cb433b0a410df7e74771f9d699b225f076 100644 (file)
@@ -1294,6 +1294,14 @@ static ProxyMappingStats_t& operator+=(ProxyMappingStats_t& a, const ProxyMappin
   return a;
 }
 
+static RemoteLoggerStats_t& operator+=(RemoteLoggerStats_t &a, const RemoteLoggerStats_t& b)
+{
+  for (const auto& [key, entry] : b) {
+    a[key] += entry;
+  }
+  return a;
+}
+
 // This function should only be called by the handler to gather
 // metrics, wipe the cache, reload the Lua script (not the Lua config)
 // or change the current trace regex, and by the SNMP thread to gather
@@ -1346,6 +1354,7 @@ template vector<ComboAddress> broadcastAccFunction(const std::function<vector<Co
 template vector<pair<DNSName, uint16_t>> broadcastAccFunction(const std::function<vector<pair<DNSName, uint16_t>>*()>& fun); // explicit instantiation
 template ThreadTimes broadcastAccFunction(const std::function<ThreadTimes*()>& fun);
 template ProxyMappingStats_t broadcastAccFunction(const std::function<ProxyMappingStats_t*()>& fun);
+template RemoteLoggerStats_t broadcastAccFunction(const std::function<RemoteLoggerStats_t*()>& fun);
 
 static int serviceMain(int argc, char* argv[], Logr::log_t log)
 {
index 8bb93431d9482d5740e91bfd3a6b1bcfddb8237b..59ead712916a2526f988d98597e3acdfc19fcb71 100644 (file)
@@ -188,6 +188,9 @@ typedef MTasker<std::shared_ptr<PacketID>, PacketBuffer, PacketIDCompare> MT_t;
 extern thread_local std::unique_ptr<MT_t> MT; // the big MTasker
 extern thread_local std::unique_ptr<RecursorPacketCache> t_packetCache;
 
+using RemoteLoggerStats_t = std::unordered_map<std::string, RemoteLoggerInterface::Stats>;
+
+
 extern bool g_logCommonErrors;
 extern size_t g_proxyProtocolMaximumSize;
 extern std::atomic<bool> g_quiet;
index 98caa91af35c8e0575935b4fcbd874c44b9e20af..1b126b403cb8191440ef84a0884d4deeb7b2fb4e 100644 (file)
@@ -66,6 +66,7 @@ public:
 
   virtual ~RemoteLoggerInterface() {};
   virtual Result queueData(const std::string& data) = 0;
+  virtual std::string address() const = 0;
   virtual std::string toString() const = 0;
   virtual const std::string name() const = 0;
   bool logQueries(void) const { return d_logQueries; }
@@ -79,6 +80,15 @@ public:
     uint64_t d_pipeFull{};
     uint64_t d_tooLarge{};
     uint64_t d_otherError{};
+
+    Stats& operator += (const Stats& rhs)
+    {
+      d_queued += rhs.d_queued;
+      d_pipeFull += rhs.d_pipeFull;
+      d_tooLarge += rhs.d_tooLarge;
+      d_otherError += rhs.d_otherError;
+      return *this;
+    }
   };
 
   virtual Stats getStats() const = 0;
@@ -102,6 +112,11 @@ public:
                bool asyncConnect=false);
   ~RemoteLogger();
 
+  std::string address() const override
+  {
+    return d_remote.toStringWithPort();
+  }
+
   [[nodiscard]] Result queueData(const std::string& data) override;
   const std::string name() const override
   {