]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Try to be smart: if to_string() or toLogString() is there, use it.
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 19 May 2022 11:06:57 +0000 (13:06 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 19 May 2022 13:12:59 +0000 (15:12 +0200)
pdns/logging.hh
pdns/pdns_recursor.cc
pdns/recursordist/rec-main.cc
pdns/recursordist/rec-tcp.cc

index 01e0d7a685f15efc5f1b793f65ea51eba212d377..f4ed25c0d7419a72c263ee61da5f54b2df2ab13c 100644 (file)
@@ -50,6 +50,36 @@ struct Entry
   Logr::Priority d_priority; // (syslog) priority)
 };
 
+// Warning: some meta-programming is going on.  We define helper
+// templates that can be used to see if specific string output
+// functions are available.  If so, we use those instead of << into an
+// ostringstream. Note that this decision happpens compile time.
+// Some hints taken from https://www.cppstories.com/2019/07/detect-overload-from-chars/
+// (I could not get function templates with enabled_if<> to work in this case)
+//
+// Default: std::string(T) is not available
+template <typename T, typename = void>
+struct is_to_string_available : std::false_type
+{
+};
+
+// If std::string(T) is available this template is used
+template <typename T>
+struct is_to_string_available<T, std::void_t<decltype(std::to_string(std::declval<T>()))>> : std::true_type
+{
+};
+
+// Same mechanism for t.toLogString()
+template <typename T, typename = void>
+struct is_toLogString_available : std::false_type
+{
+};
+
+template <typename T>
+struct is_toLogString_available<T, std::void_t<decltype(std::declval<T>().toLogString())>> : std::true_type
+{
+};
+
 template <typename T>
 struct Loggable : public Logr::Loggable
 {
@@ -60,26 +90,22 @@ struct Loggable : public Logr::Loggable
   }
   std::string to_string() const
   {
-    std::ostringstream oss;
-    oss << _t;
-    return oss.str();
+    if constexpr (std::is_same_v<T, std::string>) {
+      return _t;
+    }
+    else if constexpr (is_to_string_available<T>::value) {
+      return std::to_string(_t);
+    }
+    else if constexpr (is_toLogString_available<T>::value) {
+      return _t.toLogString();
+    }
+    else {
+      std::ostringstream oss;
+      oss << _t;
+      return oss.str();
+    }
   }
 };
-template <>
-inline std::string Loggable<DNSName>::to_string() const
-{
-  return _t.toLogString();
-}
-template <>
-inline std::string Loggable<ComboAddress>::to_string() const
-{
-  return _t.toLogString();
-}
-template <>
-inline std::string Loggable<std::string>::to_string() const
-{
-  return _t;
-}
 
 template <typename T>
 struct IterLoggable : public Logr::Loggable
index 5e4cdb9d8fea10556c8cb716e5049f9f0468361e..8fd633136b947a69aecd36f5bd93ce36acbf50dd 100644 (file)
@@ -2384,7 +2384,7 @@ void makeUDPServerSockets(deferredAdd_t& deferredAdds, std::shared_ptr<Logr::Log
     deferredAdds.emplace_back(fd, handleNewUDPQuestion);
     g_listenSocketsAddresses[fd] = sin; // this is written to only from the startup thread, not from the workers
     SLOG(g_log << Logger::Info << "Listening for UDP queries on " << sin.toStringWithPort() << endl,
-         log->info(Logr::Info, "Listening for queries", "protocol", Logging::Loggable("UDP"), "address", Logging::Loggable(sin.toStringWithPort())));
+         log->info(Logr::Info, "Listening for queries", "protocol", Logging::Loggable("UDP"), "address", Logging::Loggable(sin)));
   }
 }
 
index a1ee629a87ee105ba9e167f508b7f9e4abc9b593..4c6baded67efe9e840529088acdef1266fc3b4f4 100644 (file)
@@ -172,7 +172,7 @@ static void setCPUMap(const std::map<unsigned int, std::set<int>>& cpusMap, unsi
       g_log << Logger::Info << endl;
     }
     else {
-      log->info(Logr::Info,  "CPU affinity has been set", "thread", Logging::Loggable(n), "cpumap", Logging::IterLoggable(cpuMapping->second.begin(), cpuMapping->second.end()));
+      log->info(Logr::Info, "CPU affinity has been set", "thread", Logging::Loggable(n), "cpumap", Logging::IterLoggable(cpuMapping->second.begin(), cpuMapping->second.end()));
     }
   }
   else {
index f3ae5393ab52a4f3c1db655da0be836cde2cc27d..599350af59acc261198a72dcee2f0180a07336d7 100644 (file)
@@ -1100,6 +1100,6 @@ void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set<int>& tcpSockets
     // we don't need to update g_listenSocketsAddresses since it doesn't work for TCP/IP:
     //  - fd is not that which we know here, but returned from accept()
     SLOG(g_log << Logger::Info << "Listening for TCP queries on " << sin.toStringWithPort() << endl,
-         log->info(Logr::Info, "Listening for queries", "protocol", Logging::Loggable("TCP"), "address", Logging::Loggable(sin.toStringWithPort())));
+         log->info(Logr::Info, "Listening for queries", "protocol", Logging::Loggable("TCP"), "address", Logging::Loggable(sin)));
   }
 }