如何使用journalctl 进行时间过滤和查看非日记文件?

如何使用journalctl 进行时间过滤和查看非日记文件?

我正在尝试搜索数十个未发送到 systemd-journald 的日志文件,并希望按时间过滤结果,就像journalctl 的-S(自)和-U(直到)那样。

  • 选项 1:编写一个程序来读取行、解析时间戳、打印过滤后的输出
  • 选项 2:使用 Ubuntu dateutils 包中的 /usr/bin/dateutils.dgrep
  • 选项 3:将日志文件转换为日志格式并使用journalctl --root $dir -S xxx -U yyy

我从#1开始,意识到我正在重新发明轮子,尝试了#2,发现它非常慢,然后看了#3,主要是因为它很快,很完美,并且吸引了很多“眼球”(尤其是“付费眼球”) ”)看着它。

那么,是否有一个工具可以将 syslog 样式的日志文件转换为日志文件,以便可以按时间过滤条目? Systemd-cat不起作用,因为不允许伪造时间戳:生成的日志文件会说所有事情几乎在同一时间发生。

有什么建议么?

谢谢!

编辑:

日志文件> 100MB,有接近一百个,时间戳是简单的系统日志样式“MMM DD HH:MM:SS”,我只想说“显示这两个时间之间的日志条目” 。

选项#1是“编写一个程序来完成它”,但我确信这个轮子已经被重新发明了很多次;如果再增加一个(平庸的)轮子,我会觉得很愚蠢。

选项#2 连一个文件都没有完成,半小时后我就放弃了。本质上,我想要一个可以重复使用的快速通用解决方案,并且journalctl看起来像是答案的一个很好的部分。

我认为这journalctl利用了日志文件单调递增的时间戳,并使用二分搜索来查找给定时间范围内的记录。dateutils.dgrep( )程序dategrep不允许做出这样的假设,这使得它在一月份比糖蜜慢。

编辑2:

看起来编写一个简短的脚本来解析输入日志,以日志导出格式发出记录,并使用 systemd-journal-remote 生成日志文件就可以了:

journalctl -n 10 -o export > journal.txt
/lib/systemd/systemd-journal-remote -o test.journal journal.txt
journalctl --file=test.journal -S "yyyy-mm-dd hh:mm:ss" -U "yyyy-mm-dd hh:mm:ss"
   (log entries for time range shown)
journalctl --verify --file=test.journal

PASS: test.journal 

最初我认为这些__CURSOR行可能包含密封校验和,但删除它们并没有明显的效果。看来 Ubuntu 20.04 上默认情况下未启用前向安全密封,但 journalctl 确实会检测日志条目是否不是单调递增的:

rm -f test.journal
/lib/systemd/systemd-journal-remote -o test.journal journal.txt
/lib/systemd/systemd-journal-remote -o test.journal journal.txt
journalctl --verify --file=test.journal

3947a0: Entry timestamp out of synchronization                                                                                           
File corruption detected at test.journal:3947a0 (of 8388608 bytes, 44%).                                                                 
FAIL: test.journal (Bad message)

看来将任意日志文件导入日志格式并使用journalctl 访问它是相当容易的。

答案1

选项 1 - 按时间过滤日志文件(跳过日志转换)

我正在尝试搜索数十个未发送到 systemd-journald 的日志文件,并希望按时间过滤结果,就像journalctl 的 -S (自)和 -U (直到)那样。

如果您只想查看特定日期时间范围内的系统日志样式日志文件,请尝试super-speedy-syslog-searcher。这使用了super-speedy-syslog-searchersystemd 日志日志服务的功能并跳过了它的使用。

假设你有已安装铁锈, 跑步

$ cargo install super_speedy_syslog_searcher

然后s4在包含日志文件的目录上运行

$ s4 /logs

要限制特定的日期时间范围,请传递-a-b选项以按日期时间进行过滤。使用日期时间过滤处理日志文件的示例

$ cat /tmp/logs/kernel.log
<6>Jan  1 13:58:25 HOST kernel: [44033.150723] eth0: link up (100Mbps/Full duplex)
<6>Jan  2 12:01:00 HOST kernel: [194033.150723] loop7: detected capacity change from 0 to 113888

$ cat /tmp/logs/syslog.1
<29>Jan  1 13:58:25 HOST netifd: Network device 'eth0' link is up
<86>Jan  3 15:00:36 HOST dropbear[23732]: Exit (root): Disconnect received

$ s4 -a "2023-01-02T00:00:00Z" -b "2023-01-03T00:00:00Z" /tmp/logs/
<6>Jan  2 12:01:00 HOST kernel: [194033.150723] loop7: detected capacity change from 0 to 113888

选项 2 - 将日志文件转换为日志文件

有没有一种工具可以将系统日志样式的日志文件转换为日志文件,以便可以按时间过滤条目?

概述

转换系统日志的一系列操作如下:

  1. 使用super-speedy-syslog-searcher使用特殊格式的日期时间重新打印日志。
  2. 使用journalctl将每个系统日志消息转换为面向行的基本记录器消息日记帐导出格式
  3. 使用systemd-journal-remote导入消息

1.用于super-speedy-syslog-searcher重新打印日志文件

/tmp/logs/syslog.1给定一个包含 syslog 样式消息的日志文件

<29>Jan  1 13:58:25 HOST netifd: Network device 'eth0' link is up
<86>Jan  3 15:00:36 HOST dropbear[23732]: Exit (root): Disconnect received

使用super-speedy-syslog-searcher( s4),重新打印文件名 ( ) 和前导日期时间作为UTC 时区 ( ) 中-n以微秒 ( ) 为单位的 Unix 纪元 ( ) 的行。-d '%s000000'-u

$ s4 -n -u -d '%s000000' /tmp/logs/syslog.1
syslog.1:1672610305000000:<29>Jan  1 13:58:25 HOST netifd: Network device 'eth0' link is up
syslog.1:1672786836000000:<86>Jan  3 15:00:36 HOST dropbear[23732]: Exit (root): Disconnect received

2.用于journalctl将syslog消息转换为journal格式消息

以下是使用以下命令创建最小设计日志格式日志消息的示例logger

$ echo "SYSLOG_IDENTIFIER=logger
MESSAGE=one journal logger message
MESSAGE_ID=$(uuidgen)" | logger --journald -s

$ journalctl -n1 -t logger
Feb 03 00:48:01 HOST logger[445736]: one journal logger message

这是导出到的消息日记帐导出格式

$ journalctl -n1 --identifier=logger --output=export
__CURSOR=s=4a35367b4dd3403b948f1a5ff2fb3515;i=474833;b=5285cccfe2f9481ca12589f5511b8c57;m=dd9ee>
__REALTIME_TIMESTAMP=1675414081923660
__MONOTONIC_TIMESTAMP=951851827460
_BOOT_ID=5286cccfe2f9481ca1ea8cf5221b8c5e
_UID=0
_GID=0
_MACHINE_ID=333fa82c526bba518cdc8c2262e6d480
_HOSTNAME=HOST
_TRANSPORT=journal
SYSLOG_IDENTIFIER=logger
MESSAGE=one journal logger message
MESSAGE_ID=4ebd2168-30bf-4258-bf0f-54b5811674e1
_PID=445736
_COMM=logger
_SOURCE_REALTIME_TIMESTAMP=1675414081923606

3.用于systemd-journal-remote导入日志日志消息

要导入人为的消息,请使用 重新发送类似的数据到日志服务systemd-journal-remote

对于日志消息,每个新日志条目仅需要参数MESSAGE_ID, MESSAGE, _TRANSPORT, __REALTIME_TIMESTAMP, _SOURCE_REALTIME_TIMESTAMP。设置。_TRANSPORTsyslog覆盖值__REALTIME_TIMESTAMP_SOURCE_REALTIME_TIMESTAMP使用自 Unix 纪元以来以微秒为单位的日期时间戳记。为了太平洋标准时间 2023 年 1 月 1 日 15:00:36,值为1672614036000000

$ echo "\
__REALTIME_TIMESTAMP=1672614036000000
_TRANSPORT=syslog
MESSAGE_ID=4ebd2168-30bf-4258-bf0f-54b5811674e1
MESSAGE=one journal logger message
SYSLOG_IDENTIFIER=logger
_SOURCE_REALTIME_TIMESTAMP=1672614036000000
" | /usr/lib/systemd/systemd-journal-remote --output=/tmp/tmp.journal -

$ journalctl --output=short-full --file=/tmp/tmp.journal
Sun 2023-01-01 15:00:36 PST logger: one journal logger message

将 1.、2. 和 3. 放在一起

将所有这些内容放在一个简短的 shell 脚本中,该脚本会将日志文件目录处理/tmp/logs为日志文件,位于/tmp/logsj.

给定 syslog 样式的日志文件:

$ cat /tmp/logs/kernel.log
<6>Jan  1 13:58:25 HOST kernel: [44033.150723] eth0: link up (100Mbps/Full duplex)
<6>Jan  2 12:01:00 HOST kernel: [194033.150723] loop7: detected capacity change from 0 to 113888

$ cat /tmp/logs/syslog.1
<29>Jan  1 13:58:25 HOST netifd: Network device 'eth0' link is up
<86>Jan  3 15:00:36 HOST dropbear[23732]: Exit (root): Disconnect received

kernel.log使用如下方式重新打印文件s4

$ s4 --color=never -n -u -d '%s000000' /tmp/logs/kernel.log | tail -n1
kernel.log:1672689660000000:<6>Jan  2 12:01:00 HOST kernel: [194033.150723] loop7: detected capacity change from 0 to 113888

:请注意,前置字段由(默认)分隔。

将 下的每个 syslog 样式日志文件处理/tmp/logs为 path 下的相应日志文件/tmp/logsj。这设置SYSLOG_IDENTIFIER为文件名,不包括文件扩展名。创建的日志文件是源文件的名称加上.journal.

#!/usr/bin/env bash

mkdir /tmp/logsj

while read line; do
  echo "line is '${line}'"
  name=$(echo -n "${line}" | cut -f1 -d:)
  ts=$(echo -n "${line}" | cut -f2 -d:)
  mesg=$(echo -n "${line}" | cut -f3- -d:)
  jmesg="\
__REALTIME_TIMESTAMP=${ts}
_TRANSPORT=syslog
MESSAGE_ID=$(uuidgen)
MESSAGE=${mesg}
SYSLOG_TIMESTAMP=${ts}
SYSLOG_IDENTIFIER=${name%%.*}
_SOURCE_REALTIME_TIMESTAMP=${ts}
"
  echo "${jmesg}" | /usr/lib/systemd/systemd-journal-remote "--output=/tmp/logsj/${name}.journal" -
done <<< $(s4 --color=never -n -u -d '%s000000' /tmp/logs/)

查看新的日志文件:

$ ls -l /tmp/logsj/
-rw-r----- 1 root root 8388608 Feb  3 14:36 kernel.log.journal
-rw-r----- 1 root root 8388608 Feb  3 14:36 syslog.1.journal

$ PAGER= journalctl --utc --output=short-full --directory=/tmp/logsj/
Sun 2023-01-01 21:58:25 UTC kernel: <6>Jan  1 13:58:25 HOST kernel: [44033.150723] eth0: link up (100Mbps/Full duplex)
Sun 2023-01-01 21:58:25 UTC syslog: <29>Jan  1 13:58:25 HOST netifd: Network device 'eth0' link is up
Mon 2023-01-02 20:01:00 UTC kernel: <6>Jan  2 12:01:00 HOST kernel: [194033.150723] loop7: detected capacity change from 0 to 113888
Tue 2023-01-03 23:00:36 UTC syslog: <86>Jan  3 15:00:36 HOST dropbear[23732]: Exit (root): Disconnect received

journalctl在日期时间切片上运行

$ PAGER= journalctl --utc --output=short-full --until "2023-01-01 23:00:00 UTC" --directory=/tmp
/logsj/
Sun 2023-01-01 21:58:25 UTC kernel: <6>Jan  1 13:58:25 HOST kernel: [44033.150723] eth0: link up (100Mbps/Full duplex)
Sun 2023-01-01 21:58:25 UTC syslog: <29>Jan  1 13:58:25 HOST netifd: Network device 'eth0' link is up

$ PAGER= journalctl --utc --output=short-full --since "2023-01-01 23:00:00 UTC" --directory=/tmp
/logsj/
Mon 2023-01-02 20:01:00 UTC kernel: <6>Jan  2 12:01:00 HOST kernel: [194033.150723] loop7: detected capacity change from 0 to 113888
Tue 2023-01-03 23:00:36 UTC syslog: <86>Jan  3 15:00:36 HOST dropbear[23732]: Exit (root): Disconnect received

相关内容