]> granicus.if.org Git - pdns/commitdiff
Add options to LogAction() so it can append (instead of truncate) and write without...
authorwessels <dwessels@farnsworth.verisignlabs.com>
Wed, 17 Aug 2016 22:34:11 +0000 (18:34 -0400)
committerwessels <dwessels@farnsworth.verisignlabs.com>
Wed, 17 Aug 2016 22:34:11 +0000 (18:34 -0400)
Was so happy to discover LogAction() but disappointed that it truncates
the file each time the process starts, and apparently doesn't flush the
file upon exiting.  With two new optional args, the file can be appended
rather than truncated and buffering disabled.  The defaults remain as
before, which is to say to truncate and to buffer.

pdns/README-dnsdist.md
pdns/dnsdist-console.cc
pdns/dnsdist-lua.cc
pdns/dnsdistconf.lua
pdns/dnsrulactions.hh

index b593e7d5cb1627d3f70105f6afb94a43dc385a84..87565a6cc981901e43c56ac0652d1620cf2f3388 100644 (file)
@@ -1257,7 +1257,7 @@ instantiate a server with additional parameters
     * `DelayAction(milliseconds)`: delay the response by the specified amount of milliseconds (UDP-only)
     * `DisableValidationAction()`: set the CD bit in the question, let it go through
     * `DropAction()`: drop these packets
-    * `LogAction([filename], [binary])`: Log a line for each query, to the specified file if any, to the console (require verbose) otherwise. When logging to a file, the `binary` optional parameter specifies whether we log in binary form (default) or in textual form
+    * `LogAction([filename], [binary])`: Log a line for each query, to the specified file if any, to the console (require verbose) otherwise. When logging to a file, the `binary` optional parameter specifies whether we log in binary form (default) or in textual form, the `append` optional parameter specifies whether we open the file for appending or truncate each time (default), and the `buffered` optional parameter specifies whether writes to the file are buffered (default) or not.
     * `NoRecurseAction()`: strip RD bit from the question, let it go through
     * `PoolAction(poolname)`: set the packet into the specified pool
     * `QPSPoolAction(maxqps, poolname)`: set the packet into the specified pool only if it **does not** exceed the specified QPS limits, letting the subsequent rules apply otherwise
index d3611ff5727476a19b864da5b949d1903f98dade..619f3790c9c1bde6209cf28217d382a89debac2b 100644 (file)
@@ -265,7 +265,7 @@ const std::vector<ConsoleKeyword> g_consoleKeywords{
   { "getServers", true, "", "returns a table with all defined servers" },
   { "grepq", true, "Netmask|DNS Name|100ms|{\"::1\", \"powerdns.com\", \"100ms\"} [, n]", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms" },
   { "leastOutstanding", false, "", "Send traffic to downstream server with least outstanding queries, with the lowest 'order', and within that the lowest recent latency"},
-  { "LogAction", true, "[filename], [binary]", "Log a line for each query, to the specified file if any, to the console (require verbose) otherwise. When logging to a file, the `binary` optional parameter specifies whether we log in binary form (default) or in textual form" },
+  { "LogAction", true, "[filename], [binary], [append], [buffered]", "Log a line for each query, to the specified file if any, to the console (require verbose) otherwise. When logging to a file, the `binary` optional parameter specifies whether we log in binary form (default) or in textual form, the `append` optional parameter specifies whether we open the file for appending or truncate each time (default), and the `buffered` optional parameter specifies whether writes to the file are buffered (default) or not." },
   { "makeKey", true, "", "generate a new server access key, emit configuration line ready for pasting" },
   { "MaxQPSIPRule", true, "qps, v4Mask=32, v6Mask=64", "matches traffic exceeding the qps limit per subnet" },
   { "MaxQPSRule", true, "qps", "matches traffic **not** exceeding this qps limit" },
index 8e122046cfdaf74c7c7be3387188406a5f40a84a..bd997e197ff207c8a13569407fc13f4327765ba3 100644 (file)
@@ -756,8 +756,8 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
       return std::shared_ptr<DNSAction>(new DisableValidationAction);
     });
 
-  g_lua.writeFunction("LogAction", [](const std::string& fname, boost::optional<bool> binary) {
-      return std::shared_ptr<DNSAction>(new LogAction(fname, binary ? *binary : true));
+  g_lua.writeFunction("LogAction", [](const std::string& fname, boost::optional<bool> binary, boost::optional<bool> append, boost::optional<bool> buffered) {
+      return std::shared_ptr<DNSAction>(new LogAction(fname, binary ? *binary : true, append ? *append : false, buffered ? *buffered : false));
     });
 
   g_lua.writeFunction("RCodeAction", [](int rcode) {
index 63fa897f626372268de13c5521244ac2e2200969..028f49cac8bc29040106f476d3cf44b7aa19d731 100644 (file)
@@ -171,8 +171,8 @@ end
 -- return 'not implemented' for qtype == A OR received over UDP
 -- addAction(OrRule({QTypeRule("A"), TCPRule(false)}), RCodeAction(dnsdist.NOTIMP))
 
--- log all queries to a 'dndist.log' file, in text-mode (not binary)
--- addAction(AllRule(), LogAction("dnsdist.log", false))
+-- log all queries to a 'dndist.log' file, in text-mode (not binary) appending and unbuffered
+-- addAction(AllRule(), LogAction("dnsdist.log", false, true, false))
 
 -- drop all queries with the DO flag set
 -- addAction(DNSSECRule(), DropAction())
index 9441bce9b17b003b02f5955ce69d42c45e0314b5..12c0468bba6fadcf28071747e642811be42e5173 100644 (file)
@@ -872,13 +872,18 @@ public:
   LogAction() : d_fp(0)
   {
   }
-  LogAction(const std::string& str, bool binary=true) : d_fname(str), d_binary(binary)
+  LogAction(const std::string& str, bool binary=true, bool append=false, bool buffered=true) : d_fname(str), d_binary(binary), d_append(append), d_buffered(buffered)
   {
     if(str.empty())
       return;
-    d_fp = fopen(str.c_str(), "w");
+    if(d_append)
+      d_fp = fopen(str.c_str(), "a+");
+    else
+      d_fp = fopen(str.c_str(), "w");
     if(!d_fp)
       throw std::runtime_error("Unable to open file '"+str+"' for logging: "+string(strerror(errno)));
+    if(!d_buffered)
+      setbuf(d_fp, 0);
   }
   ~LogAction()
   {
@@ -913,6 +918,8 @@ private:
   string d_fname;
   FILE* d_fp{0};
   bool d_binary{true};
+  bool d_append{false};
+  bool d_buffered{true};
 };