From: Alan T. DeKok Date: Wed, 22 Nov 2023 15:07:09 +0000 (-0500) Subject: add file destination X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1c5cf9456708e7f9a458be8f85aed7df9b68feb7;p=thirdparty%2Ffreeradius-server.git add file destination --- diff --git a/doc/antora/modules/reference/pages/xlat/log.adoc b/doc/antora/modules/reference/pages/xlat/log.adoc index 0f22431560e..9a94a77d187 100644 --- a/doc/antora/modules/reference/pages/xlat/log.adoc +++ b/doc/antora/modules/reference/pages/xlat/log.adoc @@ -17,7 +17,7 @@ Logs a message at a DEBUG level. This function returns nothing. The DEBUG messages are printed only when the server has the debug flag set. -== %log.destination(_string_, [_uint32_]) +== %log.destination(_string_, [_uint32_], [_filename_]) The `%log.destination()` function updates the current request to add a new debug log destination. The second argument sets the debug level (0..4). If omitted, the default is `2`. The special value `0` will remove the named log destination. @@ -27,6 +27,12 @@ This function is normally used to _add_ a new log destination. Any extra debug An existing log destination can be set multiple times. The first time it is set, the log destination is added. The second and subsequent times it is set, the log level is changed. The server will not send duplicate messages to the same logging destination. +If a filename is specified, then the first argument must be a log section which has `destination = files`. If so, that section is used as a template for log configuration. However, the given `filename` is used instead of the `filename` in the log section. + +This parameter allows for logging to go to a file which is specific to a particular request. + +When the request finishes, the file is closed. Multiple requests may use the same file, however there is no inter-request locking, so log messages might be interspersed. + .Log Configuration in radiusd.conf ---- log tmp { diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index 3d3c57d69c7..7e3ef596b00 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -1152,9 +1152,16 @@ static xlat_action_t xlat_func_log_warn(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcurso return XLAT_ACTION_DONE; } +static int _log_dst_free(fr_log_t *log) +{ + close(log->fd); + return 0; +} + static xlat_arg_parser_t const xlat_func_log_dst_args[] = { { .required = true, .type = FR_TYPE_STRING }, { .required = false, .type = FR_TYPE_UINT32 }, + { .required = false, .type = FR_TYPE_STRING }, XLAT_ARG_PARSER_TERMINATOR }; @@ -1171,11 +1178,11 @@ static xlat_action_t xlat_func_log_dst(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor UNUSED xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *args) { - fr_value_box_t *dst, *lvl; - fr_log_t *log; + fr_value_box_t *dst, *lvl, *file; + fr_log_t *log, *dbg; uint32_t level = 2; - XLAT_ARGS(args, &dst, &lvl); + XLAT_ARGS(args, &dst, &lvl, &file); if (!dst || !*dst->vb_strvalue) { request_log_prepend(request, NULL, L_DBG_LVL_OFF); @@ -1187,7 +1194,33 @@ static xlat_action_t xlat_func_log_dst(UNUSED TALLOC_CTX *ctx, UNUSED fr_dcursor if (lvl) level = lvl->vb_uint32; - request_log_prepend(request, log, level); + if (!file || (log->dst != L_DST_FILES)) { + request_log_prepend(request, log, level); + return XLAT_ACTION_DONE; + } + + /* + * Clone it. + */ + MEM(dbg = talloc_memdup(request, log, sizeof(*log))); + + /* + * Open the new filename. + */ + dbg->file = talloc_strdup(dbg, file->vb_strvalue); + dbg->fd = open(dbg->file, O_WRONLY | O_CREAT | O_CLOEXEC); + if (!dbg->fd) { + REDEBUG("Failed opening %s - %s", dbg->file, fr_syserror(errno)); + talloc_free(dbg); + return XLAT_ACTION_DONE; + } + + /* + * Ensure that we close the file handle when done. + */ + talloc_set_destructor(dbg, _log_dst_free); + + request_log_prepend(request, dbg, level); return XLAT_ACTION_DONE; }