在较旧的 Linux 系统中,该logger
命令可用于将日志消息发送到 syslog。
阅读logger
在 Arch Linux 中将其消息记录到哪里?,似乎syslog
消息和命令行应用程序只与日志logger
对话systemd
是否设置了用于消息转发的套接字。
那么这个命令的现代对应词是什么logger
?如何从命令行直接向 systemd 日志发送消息?
答案1
systemd-cat
相当于logger
:
echo 'hello' | systemd-cat
在另一个终端中运行journalctl -f
:
Feb 07 13:38:33 localhost.localdomain cat[15162]: hello
优先级仅由字符串的一部分指定:
echo 'hello' | systemd-cat -p info
echo 'hello' | systemd-cat -p warning
echo 'hello' | systemd-cat -p emerg
警告用粗体字标出,紧急情况用粗体字标出且为红色。很吓人。
您还可以使用任意的“标识符”来指定应用程序名称。这些类似于 syslog 的旧功能,但您不必拘泥于古老的东西,例如lpr
uucp
nntp
或始终具有描述性的local0
through local7
。
echo 'hello' | systemd-cat -t someapp -p emerg
记录为:
Feb 07 13:48:56 localhost.localdomain someapp[15278]: hello
答案2
由于问题提到了 Arch Linux(从第一天起就由 systemd 控制)和日志记录,我猜测它与 systemd 服务的日志记录有关。以下是另一种日志记录技术为了从 systemd 服务单元调用的 shell 脚本. systemd 可以(默认情况下)设置为监听服务进程的 stderr 和/或 stdout,并将消息转发到日志。当消息以 3 个字符的前缀开头时'<' N '>'
,其中否是一个从 0 到 7 的数字,systemd 将其解释为日志级别,省略它,并在指定的级别记录其余的字符串。
它很方便,因为任何命令的任何 stderr 消息都会自动以错误级别记录。另一个 fd 被保留用于以任意不同的严重程度进行记录。
这当然适用于所有程序,而不仅仅是 shell 脚本。
例子
Ashell 脚本(在这种情况下为 Bash,依赖于进程替换和trap ... EXIT
行为),取自真实服务的ExecStartPre
脚本:
#!/bin/bash
# Redirect stderr such that any message is reported as an error to journald by
# prepending '<3>' to it. Use fd 4 (the saved stderr) to directly report other
# severity levels.
exec 4>&2 2> >(while read -r REPLY; do printf >&4 '<3>%s\n' "$REPLY"; done)
# Systemd can kill the logging subshell swiftly when we exit, and lose messages.
# Close the subshell before exiting the main program explicitly. This will block
# until the read builtin reads the EOF.
trap 'exec >&2-' EXIT
### From this point on, all stderr messages will be logged to syslog as errors
### via the subshell running the while loop. Fd 4 is the old stderr, and may
### be used to specify non-error level:
echo >&2 "This message is logged as an error, red and bold."
echo >&4 "<5>This is logged as a notice-level message, dim and boring."
echo >&4 "This is logged at the default severity level, 'info' unless changed."
中的设置单元文件通常不需要特别设置。stderr 日志记录开箱即用,除非在全局覆盖systemd-系统配置文件(5)或日志配置文件(5). 默认值为:
[Service]
; These defaults may be overridden in systemd-system.conf(5).
;StandardError=journal
;StandardOutput=journal
; These defaults may be overridden in journald.conf(5).
;LogLevelMax=debug
;LogRateLimitIntervalSec=10000
;LogRateLimitBurst=30s
; Extra fields may be added to every message.
;LogExtraFields=
;; Other settings:
; Defaults to process name. NOT the unit name, but rather basename(3) of the $0.
;SyslogIdentifier=
; For messages written without the <N> prefix.
;SyslogLevel=info
;SyslogFacility=daemon
; For completeness only: The level-parsing machinery can be disabled, but that
; was the whole point...
;SyslogLevelPrefix=true
请注意,systemd 重定向全部通过设置调用的命令Exec*
,不仅仅是主服务进程ExecStart
,还有ExecStartPre
,ExecStartPost
等等。
运行示例,将上述脚本另存为logging-test.sh
,使用 systemd-run 作为临时单元运行,然后查询每个日志记录的完整属性。如果您没有看到信息级别消息,请检查 journald.conf 是否将存储在日志中的日志记录级别限制为更高的值。
$ systemd-run --user --wait ./logging-test.sh
$ journalctl -t logging-test.sh
$ journalctl -t logging-test.sh -o json-pretty
这日志记录级别定义在sd 守护进程(3):
#define SD_EMERG "<0>" /* system is unusable */
#define SD_ALERT "<1>" /* action must be taken immediately */
#define SD_CRIT "<2>" /* critical conditions */
#define SD_ERR "<3>" /* error conditions */
#define SD_WARNING "<4>" /* warning conditions */
#define SD_NOTICE "<5>" /* normal but significant condition */
#define SD_INFO "<6>" /* informational */
#define SD_DEBUG "<7>" /* debug-level messages */
参考
- systemd.exec(5),日志记录和标准输入/输出。
- sd 守护进程(3)。
- systemd-系统配置文件(5)(文件名通常为
systemd.conf
,这里命名为 man page)。 - 日志配置文件(5)。