Commit c4e4bd6a authored by Evan Hunt's avatar Evan Hunt
Browse files

[master] dnstap size and versions options

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]
parent 5b4d6d2f
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
......
......@@ -3036,7 +3036,6 @@ configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) {
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;
......@@ -3086,6 +3085,9 @@ configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) {
}
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");
......@@ -3104,6 +3106,32 @@ configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) {
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,
......@@ -3168,9 +3196,12 @@ configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) {
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)
......@@ -13689,7 +13720,7 @@ ns_server_dnstap(ns_server_t *server, isc_lex_t *lex, isc_buffer_t **text) {
}
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);
......
/*
* 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;
};
/*
* 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;
};
......@@ -21,7 +21,7 @@ options {
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;
......
......@@ -349,7 +349,7 @@ if [ -n "$PYTHON" ] ; then
$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
......
......@@ -4416,7 +4416,7 @@ badresp:1,adberr:0,findfail:0,valfail:0]
[ <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> ; ]
......@@ -5000,6 +5000,19 @@ badresp:1,adberr:0,findfail:0,valfail:0]
(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
......
......@@ -128,6 +128,19 @@
<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
......
......@@ -1437,6 +1437,46 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
}
}
}
/* 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);
......
......@@ -104,6 +104,8 @@ struct dns_dtenv {
isc_region_t version;
char *path;
dns_dtmode_t mode;
isc_uint64_t max_size;
isc_uint32_t rolls;
isc_stats_t *stats;
};
......@@ -241,6 +243,8 @@ dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
CHECK(ISC_R_FAILURE);
}
env->mode = mode;
env->max_size = 0;
env->rolls = ISC_LOG_ROLLNEVER;
env->fopt = *foptp;
*foptp = NULL;
......@@ -274,6 +278,22 @@ dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
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;
......@@ -691,6 +711,14 @@ dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype,
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;
......
......@@ -152,6 +152,24 @@ dns_dt_create(isc_mem_t *mctx, dns_dtmode_t mode, const char *path,
*\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);
/*%<
......
......@@ -107,6 +107,7 @@ static cfg_type_t cfg_type_key;
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;
......@@ -1297,6 +1298,18 @@ static cfg_type_t cfg_type_dnstap = {
/*%
* 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,
......@@ -1306,6 +1319,8 @@ static cfg_type_t cfg_type_dtmode = {
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 }
};
......@@ -2384,7 +2399,6 @@ static cfg_type_t cfg_type_sizenodefault = {
/*%
* 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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment