Systemd

在不重新載入的情況下更改正在執行的 SystemD 服務的 JournalD 日誌級別

  • March 7, 2022

我有一個用 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

相反,如果選擇寫入日誌的內容,通常記錄所有內容,然後從日誌中過濾您想要的內容。這樣,如果出現問題,您將能夠在不重現問題的情況下閱讀調試內容。

您可以使用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="

但是這些都不能實時配置。對於實時配置,絕對只是記錄所有內容並依賴過濾器來讀取。

引用自:https://unix.stackexchange.com/questions/693137