我有一个用 Python 编写的简单服务,它使用 SystemD JournalHandler 进行日志记录(SysLogHandler 应该类似地工作)。
# 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)
这是运行此服务的 SystemD 配置:
# myservice.service
[Unit]
Description=Python logging test
[Service]
ExecStart=/usr/bin/python3 .../myservice.py
Type=simple
[Install]
WantedBy=multi-user.target
现在这将始终将所有内容记录到 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
是否可以在运行时更改此 SystemD 服务的日志记录配置,后它已经启动(级别为 DEBUG) - 无需重新加载/重新启动服务?我想完全避免在 Python 代码中设置日志级别,而是让 SystemD 处理日志级别。
基本上我想这样称呼:
# 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
相反,如果选择将哪些内容写入日志,则通常可以记录所有内容,然后从日志中过滤出您想要的内容。这样,如果出现问题,您将能够读取调试内容,而无需重现问题。
您可以使用journalctl --priority
过滤日志级别。 man journalctl
说:
-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.
我运行了你的 python 脚本几秒钟来演示。在我的终端中,debug
有灰色、info
白色、warning
琥珀色和error
红色。
情况1:无过滤器。
$ 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
情况 2:警告过滤器(详细语法)
$ 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
案例 3:信息和警告范围过滤器(简单语法)
$ 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
如果您确实想阻止特定级别的日志记录,请参阅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
。这有:
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="
但这些无法实时配置。对于实时配置,绝对只是记录所有内容并依赖过滤器来读取。