]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/log: redesign startup and target selection
authorVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 26 Jul 2021 18:58:50 +0000 (20:58 +0200)
committerTomas Krizek <tomas.krizek@nic.cz>
Thu, 29 Jul 2021 09:42:35 +0000 (11:42 +0200)
- add lua set_log_target() + docs
- default to 'stderr' (manual runs)
- switch to 'syslog' in distro-preconfig.lua
- a few minor tweaks

daemon/engine.c
daemon/lua/distro-preconfig.lua.in
daemon/main.c
doc/config-logging-monitoring.rst
lib/log.c
lib/log.h
tests/pytests/kresd.py

index e5d02bac74ed756fb306159507064b354f39238d..4d8cad7c5a836028009fe847b621fa803b581a1a 100644 (file)
@@ -27,6 +27,7 @@
 #include "lib/defines.h"
 #include "lib/cache/cdb_lmdb.h"
 #include "lib/dnssec/ta.h"
+#include "lib/log.h"
 
 /* Magic defaults for the engine. */
 #ifndef LRU_RTT_SIZE
@@ -175,6 +176,41 @@ static int l_get_log_level(lua_State *L)
        return 1;
 }
 
+static int l_set_log_target(lua_State *L)
+{
+       const int params = lua_gettop(L);
+       if (params > 1)
+               goto bad_call;
+       // set
+       if (params == 1) {
+               const char *t_str = lua_tostring(L, 1);
+               if (!t_str)
+                       goto bad_call;
+               kr_log_target_t t;
+               if (strcmp(t_str, "syslog") == 0) {
+                       t = LOG_TARGET_SYSLOG;
+               } else if (strcmp(t_str, "stdout") == 0) {
+                       t = LOG_TARGET_STDOUT;
+               } else if (strcmp(t_str, "stderr") == 0) {
+                       t = LOG_TARGET_STDERR;
+               } else {
+                       lua_error_p(L, "unknown log target '%s'", t_str);
+               }
+               kr_log_target_set(t);
+       }
+       // get
+       const char *t_str = NULL;
+       switch (kr_log_target) {
+               case LOG_TARGET_SYSLOG: t_str = "syslog"; break;
+               case LOG_TARGET_STDERR: t_str = "stderr"; break;
+               case LOG_TARGET_STDOUT: t_str = "stdout"; break;
+       } // -Wswitch-enum
+       lua_pushstring(L, t_str);
+       return 1;
+bad_call:
+       lua_error_p(L, "takes one string parameter or nothing");
+}
+
 static int handle_log_groups(lua_State *L, void (*action)(enum kr_log_group grp))
 {
        if (lua_gettop(L) != 1 || (!lua_isstring(L, 1) && !lua_istable(L, 1)))
@@ -516,6 +552,8 @@ static int init_state(struct engine *engine)
        lua_setglobal(engine->L, "set_log_level");
        lua_pushcfunction(engine->L, l_get_log_level);
        lua_setglobal(engine->L, "get_log_level");
+       lua_pushcfunction(engine->L, l_set_log_target);
+       lua_setglobal(engine->L, "set_log_target");
        lua_pushcfunction(engine->L, l_add_log_groups);
        lua_setglobal(engine->L, "add_log_groups");
        lua_pushcfunction(engine->L, l_del_log_groups);
index 69dd4a2866ae3eafd051287482b179edeee044e1..588c966037e720244db129da4348dba57e9c2f2a 100644 (file)
@@ -1,4 +1,6 @@
 -- SPDX-License-Identifier: GPL-3.0-or-later
+set_log_target('syslog') -- assume running as OS service
+
 local ffi = require('ffi')
 local id = os.getenv('SYSTEMD_INSTANCE')
 if not id then
index 736213801116c613bc659e94aec85a56434fa15d..dd14692d970d2c16e08a2247d01ad745a7ae861e 100644 (file)
@@ -418,7 +418,6 @@ int main(int argc, char **argv)
 
        the_args = &the_args_value;
        args_init(the_args);
-       kr_log_init(LOG_DEFAULT_LEVEL, LOG_TARGET_STDOUT);
        int ret = parse_args(argc, argv, the_args);
        if (ret >= 0) goto cleanup_args;
 
index ef37ed519007f9b4346d590b5687895641f9fc5b..afddb8bee13169f29c21fc238471a922f8e4f184 100644 (file)
@@ -4,9 +4,7 @@
 Logging, monitoring, diagnostics
 ********************************
 
-Knot Resolver logs to standard outputs, which is then captured by supervisor
-and sent to logging system for further processing.
-To read logs use commands usual for your distribution.
+To read service logs use commands usual for your distribution.
 E.g. on distributions using systemd-journald use command ``journalctl -u kresd@* -f``.
 
 Knot Resolver supports 6 logging levels - ``crit``, ``err``, ``warning``,
@@ -48,6 +46,16 @@ set by :func:`set_log_level`.
 
   Show current logging level.
 
+.. py:function:: set_log_target(target)
+
+  :param: String ``'syslog'``, ``'stderr'``, ``'stdout'``
+  :return: string Current logging target.
+
+     Knot Resolver logs to standard error stream by default,
+     but typical systemd units change that to ``'syslog'``.
+     That setting logs directly through systemd's facilities
+     (if available) to preserve more meta-data.
+
 .. py:function:: get_log_groups()
 
   :return: table :ref:`Groups <config_log_groups>` switched to ``debug`` level.
index 0a7f0cb38f079d0b4dc705d1e1511622ff68d518..1931d01d395aec0889c7ad50f120a3d38b8e3256 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -19,8 +19,8 @@ bool use_journal = false;
 #define use_journal false
 #endif
 
-kr_log_level_t kr_log_level = LOG_CRIT;
-kr_log_target_t kr_log_target = LOG_TARGET_STDOUT;
+kr_log_level_t kr_log_level = LOG_DEFAULT_LEVEL;
+kr_log_target_t kr_log_target = LOG_TARGET_DEFAULT;
 
 /** Set of log-groups that are on debug level.  It's a bitmap over 1 << enum kr_log_group. */
 static uint64_t kr_log_groups = 0;
@@ -127,12 +127,11 @@ void kr_log_fmt(enum kr_log_group group, kr_log_level_t level, const char *file,
                if (kr_log_group_is_set(group))
                        setlogmask(LOG_UPTO(kr_log_level));
        } else {
-
                FILE *stream;
                switch(kr_log_target) {
                case LOG_TARGET_STDOUT: stream = stdout; break;
+               default: kr_assert(false); // fall through
                case LOG_TARGET_STDERR: stream = stderr; break;
-               default: stream = stdout; break;
                }
 
                va_start(args, fmt);
@@ -245,16 +244,22 @@ void kr_log_del_group(enum kr_log_group group)
                kr_gnutls_log_level_set();
 }
 
-void kr_log_init(kr_log_level_t level, kr_log_target_t target)
+void kr_log_target_set(kr_log_target_t target)
 {
        kr_log_target = target;
-       kr_log_groups = 0;
+       if (target != LOG_TARGET_SYSLOG)
+               return;
 
+       int ret = 0;
 #if ENABLE_LIBSYSTEMD
-       use_journal = sd_booted();
+       ret = sd_booted();
+       use_journal = ret > 0;
 #endif
-       openlog(NULL, LOG_PID, LOG_DAEMON);
-       kr_log_level_set(level);
+       if (!use_journal)
+               openlog(NULL, LOG_PID, LOG_DAEMON);
+       if (ret < 0)
+               kr_log_error(SYSTEM, "failed test for systemd presence: %s\n",
+                               strerror(abs(ret)));
 }
 
 static inline bool req_has_trace_log(const struct kr_request *req)
index 0601858990546c55297413f68dbc220a17953575..6353446a2b812aadbb1b6d0b90db263abf54643e 100644 (file)
--- a/lib/log.h
+++ b/lib/log.h
@@ -17,6 +17,8 @@ typedef enum {
        LOG_TARGET_SYSLOG = 0,
        LOG_TARGET_STDERR = 1,
        LOG_TARGET_STDOUT = 2,
+       /* The default also applies *before* configuration changes it. */
+       LOG_TARGET_DEFAULT = LOG_TARGET_STDERR,
 } kr_log_target_t;
 
 /* Groups */
@@ -148,7 +150,7 @@ int kr_log_level_set(kr_log_level_t level);
 KR_EXPORT
 kr_log_level_t kr_log_level_get(void);
 KR_EXPORT
-void kr_log_init(kr_log_level_t level, kr_log_target_t target);
+void kr_log_target_set(kr_log_target_t target);
 
 #define TO_STR_A(x) #x
 #define TO_STR(x) TO_STR_A(x)
index 62835f3662e4393baf8818733203cd5ebb07267c..7eeceb68a9e09add7473474ca8d0a5a282cacc86 100644 (file)
@@ -95,7 +95,7 @@ class Kresd(ContextDecorator):
         self.logfile = open(self.logfile_path, 'w')
         self.process = subprocess.Popen(
             ['kresd', '-c', self.config_path, '-n', self.workdir],
-            stdout=self.logfile, env=os.environ.copy())
+            stderr=self.logfile, env=os.environ.copy())
 
         try:
             self._wait_for_tcp_port()  # wait for ports to be up and responding