+4572. [func] The "dnstap-output" option can now take "size" and
+ "versions" parameters to indicate the maximum size
+ a dnstap log file can grow before rolling to a new
+ file, and how many old files to retain. [RT #44502]
+
4571. [bug] Out-of-tree builds of backtrace_test failed.
4570. [cleanup] named did not correctly fall back to the built-in
const char *dpath = ns_g_defaultdnstap;
const cfg_obj_t *dlist = NULL;
dns_dtmsgtype_t dttypes = 0;
- dns_dtmode_t dmode;
unsigned int i;
struct fstrm_iothr_options *fopt = NULL;
}
if (ns_g_server->dtenv == NULL && dttypes != 0) {
+ dns_dtmode_t dmode;
+ isc_uint64_t max_size = 0;
+ isc_uint32_t rolls = 0;
obj = NULL;
CHECKM(ns_config_get(maps, "dnstap-output", &obj),
"'dnstap-output' must be set if 'dnstap' is set");
dpath = cfg_obj_asstring(obj2);
+ obj2 = cfg_tuple_get(obj, "size");
+ if (obj2 != NULL && cfg_obj_isuint64(obj2)) {
+ max_size = cfg_obj_asuint64(obj2);
+ if (max_size > SIZE_MAX) {
+ cfg_obj_log(obj2, ns_g_lctx,
+ ISC_LOG_WARNING,
+ "'dnstap-output size "
+ "%" ISC_PRINT_QUADFORMAT "u' "
+ "is too large for this "
+ "system; reducing to %lu",
+ max_size, (unsigned long)SIZE_MAX);
+ max_size = SIZE_MAX;
+ }
+ }
+
+ obj2 = cfg_tuple_get(obj, "versions");
+ if (obj2 != NULL && cfg_obj_isuint32(obj2)) {
+ rolls = cfg_obj_asuint32(obj2);
+ } else if (obj2 != NULL && cfg_obj_isstring(obj2) &&
+ strcasecmp(cfg_obj_asstring(obj2), "unlimited") == 0)
+ {
+ rolls = ISC_LOG_ROLLINFINITE;
+ } else {
+ rolls = ISC_LOG_ROLLNEVER;
+ }
+
fopt = fstrm_iothr_options_init();
fstrm_iothr_options_set_num_input_queues(fopt, ns_g_cpus);
fstrm_iothr_options_set_queue_model(fopt,
fstrm_iothr_options_set_reopen_interval(fopt, i);
}
- CHECKM(dns_dt_create(ns_g_mctx, dmode, dpath, &fopt,
- &ns_g_server->dtenv),
+ CHECKM(dns_dt_create(ns_g_mctx, dmode, dpath,
+ &fopt, &ns_g_server->dtenv),
"unable to create dnstap environment");
+
+ CHECKM(dns_dt_setupfile(ns_g_server->dtenv, max_size, rolls),
+ "unable to set up dnstap logfile");
}
if (ns_g_server->dtenv == NULL)
}
if (reopen || strcasecmp(ptr, "-reopen") == 0) {
- backups = -1;
+ backups = ISC_LOG_ROLLNEVER;
} else if ((strcasecmp(ptr, "-roll") == 0)) {
unsigned int n;
ptr = next_token(lex, text);
--- /dev/null
+/*
+ * Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+options {
+ dnstap-output unix "/tmp/dnstap.sock" size 10k versions 3;
+};
--- /dev/null
+/*
+ * Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+options {
+ dnstap-output file "/tmp/dnstap.log" size 10k versions 3;
+};
statistics-file "named.stats";
dnstap-identity "ns1";
dnstap-version "xxx";
- dnstap-output file "dnstap.out";
+ dnstap-output file "dnstap.out" size 30k versions 10;
dnstap { all; };
send-cookie no;
require-server-cookie no;
$PYTHON -c "import yaml" && HAS_PYYAML=1
fi
-if [ $HAS_PYYAML ] ; then
+if [ $HAS_PYYAML -ne 0 ] ; then
echo "I:checking dnstap-read YAML output"
ret=0
$PYTHON ydump.py "$DNSTAPREAD" "ns3/dnstap.out.save" > /dev/null || ret=1
[ <command>server-id</command> <replaceable>server_id_string</replaceable> ; ]
[ <command>directory</command> <replaceable>path_name</replaceable> ; ]
[ <command>dnstap {</command> <replaceable>message_type</replaceable> ; ... <command>}</command> ; ]
- [ <command>dnstap-output</command> ( <option>file</option> | <option>unix</option> ) <replaceable>path_name</replaceable> ; ]
+ [ <command>dnstap-output</command> ( <option>file</option> | <option>unix</option> ) <replaceable>path_name</replaceable> [ <command>size</command> <replaceable>size_spec</replaceable> ] [ <command>versions</command> ( <replaceable>number</replaceable> | <option>unlimited</option> ) ] ; ]
[ <command>dnstap-identity</command> ( <replaceable>string</replaceable> | <option>hostname</option> | <option>none</option> ) ; ]
[ <command>dnstap-version</command> ( <replaceable>string</replaceable> | <option>none</option> ) ; ]
[ <command>fstrm-set-buffer-hint</command> <replaceable>number</replaceable> ; ]
(provided with <command>libfstrm</command>) is listening on
the socket.)
</para>
+ <para>
+ If the first argument is <literal>file</literal>, then
+ two additional options can be added:
+ <command>size</command> indicates the size to which a
+ <command>dnstap</command> log file can grow before being
+ rolled to a new file, and <command>versions</command>
+ specifies the number of rolled log files to retain. These
+ are similar to the <command>size</command> and
+ <command>versions</command> options in a
+ <command>logging</comamnd> channel. The default
+ is to allow <command>dnstap</command> log files to grow to
+ any size without rolling.
+ </para>
<para>
<command>dnstap-output</command> can only be set globally
in <command>options</command>. Currently, it can only be
<section xml:id="relnotes_features"><info><title>New Features</title></info>
<itemizedlist>
+ <listitem>
+ <para>
+ <command>dnstap</command> logfiles can now be configured to
+ automatically roll when they reach a specified size. If
+ <command>dnstap-output</command> is configured with mode
+ <literal>file</command>, then it can take optional
+ <command>size</command> and <command>versions</command>
+ key-value arguments to set the logfile rolling parameters.
+ (These have the same semantics as the corresponding
+ options in a <command>logging</command> channel statement.)
+ [RT #44502]
+ </para>
+ </listitem>
<listitem>
<para>
<command>dig +ednsopt</command> now accepts the names
}
}
}
+
+ /* Check that dnstap-ouput values are consistent */
+ obj = NULL;
+ (void) cfg_map_get(options, "dnstap-output", &obj);
+ if (obj != NULL) {
+ const cfg_obj_t *obj2;
+ dns_dtmode_t dmode;
+
+ obj2 = cfg_tuple_get(obj, "mode");
+ if (obj2 == NULL) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "dnstap-output mode not found");
+ return (ISC_R_FAILURE);
+ }
+
+ if (strcasecmp(cfg_obj_asstring(obj2), "file") == 0)
+ dmode = dns_dtmode_file;
+ else
+ dmode = dns_dtmode_unix;
+
+ obj2 = cfg_tuple_get(obj, "size");
+ if (obj2 != NULL && !cfg_obj_isvoid(obj2) &&
+ dmode == dns_dtmode_unix)
+ {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "dnstap-output size "
+ "cannot be set with mode unix");
+ return (ISC_R_FAILURE);
+ }
+
+ obj2 = cfg_tuple_get(obj, "versions");
+ if (obj2 != NULL && !cfg_obj_isvoid(obj2) &&
+ dmode == dns_dtmode_unix)
+ {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "dnstap-output versions "
+ "cannot be set with mode unix");
+ return (ISC_R_FAILURE);
+ }
+ }
#endif
return (result);
isc_region_t version;
char *path;
dns_dtmode_t mode;
+ isc_uint64_t max_size;
+ isc_uint32_t rolls;
isc_stats_t *stats;
};
CHECK(ISC_R_FAILURE);
}
env->mode = mode;
+ env->max_size = 0;
+ env->rolls = ISC_LOG_ROLLNEVER;
env->fopt = *foptp;
*foptp = NULL;
return (result);
}
+isc_result_t
+dns_dt_setupfile(dns_dtenv_t *env, isc_uint64_t max_size, int rolls) {
+ REQUIRE(VALID_DTENV(env));
+
+ if (max_size != 0 && rolls != ISC_LOG_ROLLNEVER &&
+ env->mode != dns_dtmode_file)
+ {
+ return (ISC_R_INVALIDFILE);
+ }
+
+ env->max_size = max_size;
+ env->rolls = rolls;
+
+ return (ISC_R_SUCCESS);
+}
+
isc_result_t
dns_dt_reopen(dns_dtenv_t *env, int roll) {
isc_result_t result = ISC_R_SUCCESS;
REQUIRE(VALID_DTENV(view->dtenv));
+ if (view->dtenv->max_size != 0) {
+ struct stat statbuf;
+ if (stat(view->dtenv->path, &statbuf) >= 0 &&
+ (size_t) statbuf.st_size > view->dtenv->max_size) {
+ dns_dt_reopen(view->dtenv, view->dtenv->rolls);
+ }
+ }
+
TIME_NOW(&now);
t = &now;
*\li Other errors are possible.
*/
+isc_result_t
+dns_dt_setupfile(dns_dtenv_t *env, isc_uint64_t max_size, int rolls);
+/*%<
+ * Sets up the dnstap logfile limits.
+ *
+ * 'max_size' is the size a log file may grow before it is rolled
+ *
+ * 'rolls' is the number of rolled files to retain.
+ *
+ * Requires:
+ *
+ *\li 'env' is a valid dnstap environment.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS on success
+ *\li #ISC_R_INVALIDFILE if dnstap is set to use a UNIX domain socket
+ */
+
isc_result_t
dns_dt_reopen(dns_dtenv_t *env, int roll);
/*%<
static cfg_type_t cfg_type_logfile;
static cfg_type_t cfg_type_logging;
static cfg_type_t cfg_type_logseverity;
+static cfg_type_t cfg_type_logversions;
static cfg_type_t cfg_type_lwres;
static cfg_type_t cfg_type_masterselement;
static cfg_type_t cfg_type_maxttl;
/*%
* dnstap-output
*/
+static keyword_type_t dtsize_kw = { "size", &cfg_type_sizenodefault};
+static cfg_type_t cfg_type_dnstap_size = {
+ "dnstap_size", parse_optional_keyvalue, print_keyvalue,
+ doc_optional_keyvalue, &cfg_rep_uint64, &dtsize_kw
+};
+
+static keyword_type_t dtversions_kw = { "versions", &cfg_type_logversions};
+static cfg_type_t cfg_type_dnstap_versions = {
+ "dnstap_versions", parse_optional_keyvalue, print_keyvalue,
+ doc_optional_keyvalue, &cfg_rep_uint32, &dtversions_kw
+};
+
static const char *dtoutmode_enums[] = { "file", "unix", NULL };
static cfg_type_t cfg_type_dtmode = {
"dtmode", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
static cfg_tuplefielddef_t dtout_fields[] = {
{ "mode", &cfg_type_dtmode, 0 },
{ "path", &cfg_type_qstring, 0 },
+ { "size", &cfg_type_dnstap_size, 0 },
+ { "versions", &cfg_type_dnstap_versions, 0 },
{ NULL, NULL, 0 }
};
/*%
* A size in absolute values or percents.
*/
-
static cfg_type_t cfg_type_sizeval_percent = {
"sizeval_percent", parse_sizeval_percent, cfg_print_ustring,
doc_sizeval_percent, &cfg_rep_string, NULL