在journalctl中只打印时间戳和消息

在journalctl中只打印时间戳和消息

我试图从中获取最后几行,journalctl以便我可以将它们输入到我的conky.然而,journalctl默认情况下提供了太多浪费空间的垃圾:随着journalctl -u PROCESS -n 5 --no-pager -l我得到如下条目:

DATE TIME HOSTNAME PROCESS: MESSAGE

我只想打印TIME MESSAGE.我怎样才能做到这一点?


联机帮助页说有一个-o争论,但没有适合我需要的预定义格式。我尝试添加--output-fields=__REALTIME_TIMESTAMP,MESSAGE,但只显示默认输出(而不是时间戳/消息)。该论点声称只有某些格式受到影响,所以我尝试了,--output-fields=__REALTIME_TIMESTAMP,MESSAGE -o verbose但这只给了我正常的 vebose 输出。此外,显然有 4 个字段总是被打印,这对我来说已经太多了。我只想要 2:一个紧凑的时间戳和消息。

我可以使用一些 bash 魔法或 python 脚本来清理它,但这似乎有点过分了。当然有办法要求journalctl只给我一个时间戳和消息吗?

答案1

journalctl --output cat

cat
               generates a very terse output, only showing the actual message of each journal entry with no metadata, not even a timestamp. If combined with the --output-fields= option will output the listed fields for each log
               record, instead of the message.

答案2

当然有办法要求journalctl我只提供时间戳和消息吗?

不可以。截至目前(2023 年 11 月),无法journalctl在不进行后处理的情况下仅打印时间和消息。最接近你想要的是

journalctl --no-hostname -o short-full

如果这对您来说DATE TIME PROCESS: MESSAGE
还不够好,那么您唯一的选择是使用其他工具来提取/格式化该数据。
journalctl可以使用其中一种jsonexport输出模式,仅提取时间戳和消息(并将时间戳仅转换为时间) - 就像用户一样迪安树脂 在这里显示通过jq
您还可以按照用户的建议使用可用的绑定之一systemd并编写自己的工具来获取该数据马克西姆科在评论中(例如python systemd.journal
最后,如果您想实时显示消息,您可以使用journalctlinfollow模式并在每次打印一行时在前面添加一个时间戳,例如tsfrom moreutils

journalctl -f -o cat | ts '%H:%M:%S'

现在,至于为什么--output-fields=__REALTIME_TIMESTAMP,MESSAGE不只打印这两个字段......

当前手册页journalctl,“输出选项”部分指出:

--output-fields=
应包含在输出中的逗号分隔字段列表。这仅对输出有影响 通常会显示所有字段的模式(详细、导出、json、json-pretty、json-sse 和 json-seq),以及猫身上。为了 以前的、那个“__CURSOR”、“__REALTIME_TIMESTAMP”、
“__MONOTONIC_TIMESTAMP”和“_BOOT_ID”字段总是被打印

--output-fields在版本 236 中添加,但是在使用时支持过滤字段-o cat 后来才在版本 246 中添加:

Journalctl 的“-o cat”输出模式现在将显示用 --output-fields= 指定的一个或多个日志字段,而不是无条件 MESSAGE=。这对于检索没有任何修饰的非常特定的字段集非常有用。

基于以上所述,这四个字段总是被打印,除非使用 -o cat。有人会认为

journalctl -o cat --output-fields=__REALTIME_TIMESTAMP,MESSAGE

应该可以...但是打印出来

Failed to get data: Invalid argument

这是为什么?
手册页中描述了日志字段systemd.journal-fields。消息有三个时间戳字段:_SOURCE_REALTIME_TIMESTAMP__REALTIME_TIMESTAMP__MONOTONIC_TIMESTAMP(请注意,最后两个以两个下划线开头)。所有这些都以微秒为单位,格式为十进制字符串,因此它们都不符合您的要求(HH:MM:SS格式)。此外,根据同一手册页,最后两个时间戳是特殊的寻址字段(它们不能用作过滤条目的匹配项):

在序列化为外部格式(例如日记导出格式或日记 JSON 格式)期间,日记条目的地址 被序列化为以双下划线为前缀的字段。注意 当存储在日志中时,这些不是正确的字段,但对于 寻址条目的元数据。它们不能通过诸如 之类的调用作为结构化日志条目的一部分写入sd_journal_send(3)他们可能会 也不能用作匹配 sd_journal_add_match(3)

最后一句指出sd_journal_add_match(3)手册页指出:

sd_journal_add_match()添加一个匹配项来过滤日志文件的条目。与此调用一起应用的匹配将过滤可以通过sd_journal_next(3)和等调用迭代并从日志文件中读取的内容 sd_journal_get_data(3)。参数数据必须采用“FIELD=值”的形式,其中场地part 是一个短的大写字符串,仅包含 0–9、A–Z 和下划线; 不能以两个下划线开头或者是空字符串。

因此错误:__REALTIME_TIMESTAMP不是 的有效字段名称sd_journal_get_data(3)
总结一下:与is--output-fields一起使用时接受的唯一时间戳,即使这样,输出也与您想要的相距甚远,例如-o cat_SOURCE_REALTIME_TIMESTAMP

journalctl -o cat --output-fields=_SOURCE_REALTIME_TIMESTAMP,MESSAGE

印刷

1699815974366491
Supervising 9 threads of 6 processes of 1 users.
1699815968034836
[system] Successfully activated service 'org.kde.powerdevil.backlighthelper'

答案3

编辑: 请参阅这个答案反而。以下答案仅供后代保留。


这似乎是2018年实施的,参见这个公关。对于版本 236 及更高版本,您似乎可以使用--output-fields=,如 中所述--help。检查您的版本systemctl --version,我的 CentOS 7 目前(2019 年)运行版本 219,因此可能需要一些时间才能适应大多数环境。

编辑:仅供参考,EL8(截至 2021 年 4 月 12 日)运行 systemd 239,因此可用。

答案4

journalctl我不相信仅使用、--output和就可以完全满足您的要求--output-fields

您可以使用--output=json的选项journalctl,然后通过管道将其传输到jq

jq是linux json处理器。您可以使用sudo apt install jq.

选项的可用字段--output-fields未记录。您可以通过以下方式获取所有可用字段。

journalctl -n1 --output=json | jq 'keys'

您只能获取时间戳和消息,

journalctl --output=json | jq '.__REALTIME_TIMESTAMP, .MESSAGE'

从那里您可以按照您想要的方式进一步格式化/处理。我建议查看 , 的jq文档man jq

例如,要获取人类可读的时间戳,您可以..

journalctl --output=json | jq '(.__REALTIME_TIMESTAMP | tonumber/1000000 | strflocaltime("%Y-%m-%d %H:%M:%S")), .MESSAGE'

此外,要删除 json 的格式并将所有内容都放在一行(如journalctl)中,那么..

journalctl --output=json | jq -r '[(.__REALTIME_TIMESTAMP | tonumber/1000000 | strflocaltime("%Y-%m-%d %H:%M:%S")), .MESSAGE] | @tsv'

相关内容