* `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
{ "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" },
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) {
-- 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())
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()
{
string d_fname;
FILE* d_fp{0};
bool d_binary{true};
+ bool d_append{false};
+ bool d_buffered{true};
};