我试图从中获取最后几行,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
可以使用其中一种json
或export
输出模式,仅提取时间戳和消息(并将时间戳仅转换为时间) - 就像用户一样迪安树脂 在这里显示通过jq
。
您还可以按照用户的建议使用可用的绑定之一systemd
并编写自己的工具来获取该数据马克西姆科在评论中(例如python systemd.journal
)
最后,如果您想实时显示消息,您可以使用journalctl
infollow
模式并在每次打印一行时在前面添加一个时间戳,例如ts
from 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
答案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'