0

I have a simple service written in Python that is using SystemD JournalHandler for logging (SysLogHandler should work similarly).

# myservice.py
import time

import logging
from systemd.journal import JournalHandler

log = logging.getLogger('demo')
log.addHandler(JournalHandler())
log.setLevel(logging.DEBUG)


while True:
    log.debug("debug")
    log.info("info")
    log.warning("warning")
    log.error("error")
    time.sleep(3)

This is the SystemD config to run this service:

# myservice.service
[Unit]
Description=Python logging test
 
[Service]
ExecStart=/usr/bin/python3 .../myservice.py
Type=simple
 
[Install]
WantedBy=multi-user.target

Now this will always log everything to JournalD:

# journalctl -f
Mar 06 15:58:13 myhost .../myservice.py[12852]: debug
Mar 06 15:58:13 myhost .../myservice.py[12852]: info
Mar 06 15:58:13 myhost .../myservice.py[12852]: warning
Mar 06 15:58:13 myhost .../myservice.py[12852]: error

Is it possible change the logging configuration of this SystemD service at runtime, after it started already (with level DEBUG) - without reloading/restarting the service? I would like to avoid setting loglevels within my Python code at all and instead let SystemD handle the loglevel.

Basically I would like to call something like that:

# Log everything to JournalD
change-systemd-service-loglevel myservice DEBUG

# Ignore all logs < WARNING, these should not show up on journalctl
change-systemd-service-loglevel myservice WARNING

1 Answer 1

1

Instead if choosing what goes into a log, it usually makes sense to log everything, then filter what you want from a log. That way, if something goes wrong you'll be able to read the debug stuff without reproducing the issue.

You can use journalctl --priority to filter the log levels. man journalctl says:

       -p, --priority=
           Filter output by message priorities or priority ranges. Takes
           either a single numeric or textual log level (i.e. between
           0/"emerg" and 7/"debug"), or a range of numeric/text log levels
           in the form FROM..TO. The log levels are the usual syslog log
           levels as documented in syslog(3), i.e.  "emerg" (0),
           "alert" (1), "crit" (2), "err" (3), "warning" (4), "notice" (5),
           "info" (6), "debug" (7). If a single log level is specified, all
           messages with this log level or a lower (hence more important)
           log level are shown. If a range is specified, all messages within
           the range are shown, including both the start and the end value
           of the range. This will add "PRIORITY=" matches for the specified
           priorities.

I ran your python script for a few seconds to demonstrate. In my terminal debug is grey, info is white, warning is amber, and error is red.

Case 1: No filter.

$ journalctl --user -u pylog --no-hostname
Mar 07 08:54:03 systemd[1064]: Started Python logging test.
Mar 07 08:54:03 /home/stew/bin/pylog.py[953165]: debug
Mar 07 08:54:03 /home/stew/bin/pylog.py[953165]: info
Mar 07 08:54:03 /home/stew/bin/pylog.py[953165]: warning
Mar 07 08:54:03 /home/stew/bin/pylog.py[953165]: error
Mar 07 08:54:06 /home/stew/bin/pylog.py[953165]: debug
Mar 07 08:54:06 /home/stew/bin/pylog.py[953165]: info
Mar 07 08:54:06 /home/stew/bin/pylog.py[953165]: warning
Mar 07 08:54:06 /home/stew/bin/pylog.py[953165]: error

Case 2: Warning filter (verbose syntax)

$ journalctl --user -u pylog --no-hostname --priority=warning
Mar 07 08:54:03 /home/stew/bin/pylog.py[953165]: warning
Mar 07 08:54:03 /home/stew/bin/pylog.py[953165]: error
Mar 07 08:54:06 /home/stew/bin/pylog.py[953165]: warning
Mar 07 08:54:06 /home/stew/bin/pylog.py[953165]: error

Case 3: Info and warnings range filter (simple syntax)

$ journalctl --user -u pylog --no-hostname -p 4..6
Mar 07 08:54:03 systemd[1064]: Started Python logging test.
Mar 07 08:54:03 /home/stew/bin/pylog.py[953165]: info
Mar 07 08:54:03 /home/stew/bin/pylog.py[953165]: warning
Mar 07 08:54:06 /home/stew/bin/pylog.py[953165]: info
Mar 07 08:54:06 /home/stew/bin/pylog.py[953165]: warning

If you really want to prevent logging of specific levels, then see man systemd.exec:

       LogLevelMax=
           Configures filtering by log level of log messages generated by
           this unit. Takes a syslog log level, one of emerg (lowest log
           level, only highest priority messages), alert, crit, err,
           warning, notice, info, debug (highest log level, also lowest
           priority messages). See syslog(3) for details. By default no
           filtering is applied (i.e. the default maximum log level is
           debug). Use this option to configure the logging system to drop
           log messages of a specific service above the specified level. For
           example, set LogLevelMax=info in order to turn off debug logging
           of a particularly chatty unit. Note that the configured level is
           applied to any log messages written by any of the processes
           belonging to this unit, as well as any log messages written by
           the system manager process (PID 1) in reference to this unit,
           sent via any supported logging protocol. The filtering is applied
           early in the logging pipeline, before any kind of further
           processing is done. Moreover, messages which pass through this
           filter successfully might still be dropped by filters applied at
           a later stage in the logging subsystem. For example,
           MaxLevelStore= configured in journald.conf(5) might prohibit
           messages of higher log levels to be stored on disk, even though
           the per-unit LogLevelMax= permitted it to be processed.

man journal.conf. This has:

       MaxLevelStore=
           Controls the maximum log level of messages that are stored in the
           journal. As argument, takes one of "emerg", "alert", "crit", 
           "err", "warning", "notice", "info", "debug", or integer values in 
           the range of 0–7 (corresponding to the same levels). Messages 
           equal or below the log level specified are stored/forwarded, 
           messages above are dropped. Defaults to "debug" to ensure that 
           the all messages are stored in the journal and forwarded to 
           syslog. These settings may be overridden at boot time with the 
           kernel command line options "systemd.journald.max_level_store="

But these aren't configurable in real-time. For real-time configuration, definitely just log everything and depend on filters to read.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .