日志控制看起来是个查看日志的好工具,但我被一个简单的要求难住了:我想查看所有包含短语的 cron 消息update-ipsets
。
我当然可以
journalctl -u cron.service | grep update-ipsets
但你会失去 journalctl 输出的所有其他好处(颜色编码、自动分页、实时查看等)。
我试过了:
journalctl -u cron.service MESSAGE=update-ipsets
journalctl -u cron.service "MESSAGE=*update-ipsets*"
journalctl -u cron.service "MESSAGE=.*update-ipsets.*"
journalctl -u cron.service "MESSAGE=/.*update-ipsets.*/"
而且您不想通过点击tab后进行实验MESSAGE=
- 挂起(zsh / Debian Jessie)shell并且Ctrl-C也无济于事!
我有点不敢相信它没有内置这个基本功能,所以我确定我一定是错过了什么?
谢谢。
答案1
目前,journalctl 不支持字段匹配中的模式或通配符。grep
是您的最佳选择。
我遇到了同样的问题,我认为只有在作为参数传递journalctl
时才会搜索 VALUE 的完全匹配。NAME=VALUE
我的调查:
手册页
从
journalctl(1)
比赛描述中没有提到该模式:
[...] A match is in the format "FIELD=VALUE", e.g. "_SYSTEMD_UNIT=httpd.service", referring to the components of a structured journal entry. [...]
-u
手册页仅在描述选项时引用模式。-u, --unit=UNIT|PATTERN Show messages for the specified systemd unit UNIT (such as a service unit), or for any of the units matched by PATTERN.
源代码
调试日志控制
启用调试输出您可以看到仅在使用时模式才会扩展
-u
。$ SYSTEMD_LOG_LEVEL=debug journalctl -n1 -u gdm* ... Matched gdm.service with pattern _SYSTEMD_UNIT=gdm* Matched gdm.service with pattern UNIT=gdm* Journal filter: ((OBJECT_SYSTEMD_UNIT=gdm.service AND _UID=0) OR (UNIT=gdm.service AND _PID=1) OR (COREDUMP_UNIT=gdm.service AND _UID=0 AND MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1) OR _SYSTEMD_UNIT=gdm.service) ...
所有匹配均视为精确匹配,包括
UNIT
:$ SYSTEMD_LOG_LEVEL=debug journalctl -n1 UNIT=gdm.* ... Journal filter: UNIT=gdm* ...
答案2
从systemctl --version
版本开始237
,可能存在带-g/--grep
开关的 grep 模式支持,但必须在PRCE2
支持的情况下进行编译(似乎没有包含在 Debian Buster 中,>=242
是需要的,可以从安装buster-backports
)
journalctl -g ipsets*
即使没有 grep 支持,您仍然可以切换到cat
输出模式并使用grep
的匹配:
journalctl -b -o cat --no-pager | grep "update-ipsets"
如果你想要一个寻呼机,最好将结果传送到less
。你可以使用反向匹配-v / --invert-match
来排除某些消息
journalctl -b -o cat --no-pager | grep -v "ACPI" | less
另一个选择是使用json
格式:
journalctl -b -o json | jq -C . | less -R
提供详细输出,单行
{
"SYSLOG_IDENTIFIER": "kernel",
"_MACHINE_ID": "d72735cff36a41f0a5326f0bb7eb1778",
"_SOURCE_MONOTONIC_TIMESTAMP": "0",
"__REALTIME_TIMESTAMP": "1614516018297106",
"__CURSOR": "s=2b1deb3dba3e42e4a758cc8f011d19c5;i=1;b=c0f6b0e5143a4d3db9f04f00da1a4ff4;m=670dd9;t=5bc64cdc13912;x=ee44184076fc0590",
"__MONOTONIC_TIMESTAMP": "6753753",
"SYSLOG_FACILITY": "0",
"_HOSTNAME": "w16",
"PRIORITY": "5",
"_BOOT_ID": "c0f6b0e5143a4d3db9f04f00da1a4ff4",
"_TRANSPORT": "kernel",
"MESSAGE": "Linux version 4.19.0-14-amd64 ([email protected]) (gcc version 8.3.0 (Debian 8.3.0-6)) #1 SMP Debian 4.19.171-2 (2021-01-30)"
}
使用jq
您可以轻松归档消息:
$ journalctl -b -o json | jq '. | select(._COMM=="sensors")' | jq -r .MESSAGE | less
$ journalctl -b -o json | jq '. | select(._TRANSPORT=="kernel")' | jq -r .MESSAGE | head -n 1
Linux version 4.19.0-14-amd64 ([email protected]) (gcc version 8.3.0 (Debian 8.3.0-6)) #1 SMP Debian 4.19.171-2 (2021-01-30)
答案3
使用 journalctl 版本 247.3-7(作为 systemd),--grep(或 -g)选项允许过滤日志中 MESSAGE 字段包含字符串或匹配正则表达式的行。
man journalctl 说:
**-g, --grep=**
Filter output to entries where the MESSAGE= field matches the specified regular expression. PERL-compatible regular expressions are used, see pcre2pattern(3) for a detailed description of the
syntax.
If the pattern is all lowercase, matching is case insensitive. Otherwise, matching is case sensitive. This can be overridden with the --case-sensitive option, see below.
journalctl 手册和 pcre2pattern 中都没有提到,正则表达式必须用单引号或双引号括起来,并且不能有其他字符!!!
如果您以 root 身份或使用 sudo 运行以下命令:
# journalctl --grep "UFW BLOCK"
您将获得所有记录的阻止 ID 和防火墙阻止的请求的列表...
希望这有帮助!