有没有办法让 journalctl 显示“上次 foo.service 运行”的日志?

有没有办法让 journalctl 显示“上次 foo.service 运行”的日志?

我对此特别感兴趣,因为我可以查看在计时器上运行的一次性服务的输出。该--unit标志很接近,但它将服务的所有运行连接在一起。我能想到的最明显的方法是过滤 PID,但这让我担心 PID 重用/分叉的服务,而获取最后一个 PID 非常不方便。是否有其他与服务的单次运行相对应的标识符,我可以使用它们来过滤日志?

编辑:如果这是真正的答案,我会很乐意接受权威的“不”。

答案1

systemd版本开始232,我们有了调用 ID 的概念。每次运行单元时,它都有一个唯一的 128 位调用 ID。与MainPID可回收或ActiveEnterTimestamp存在解析问题的调用 ID 不同,这是一种获取特定 systemd 单元调用的所有日志的安全方法。

获取单元的最新调用 ID

$ systemctl show --value -p InvocationID openipmi
bd3eb84c3aa74169a3dcad2af183885b

要获取最新调用的日志(例如,openipmi无论它是否失败),您可以使用一行代码

$ journalctl _SYSTEMD_INVOCATION_ID=`systemctl show -p InvocationID --value openipmi.service`
-- Logs begin at Thu 2018-07-26 12:09:57 IDT, end at Mon 2019-07-08 01:32:50 IDT. --
Jun 21 13:03:13 build03.lbits openipmi[1552]:  * Starting ipmi drivers
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...fail!
Jun 21 13:03:13 build03.lbits openipmi[1552]:    ...done.

(请注意--value自 起可用systemd 230,早于InvocationID

答案2

我不确定哪个时间戳最有意义,但这对我来说很有效。希望有比systemctl showawk 更好的方法来处理时间戳 - 无法弄清楚如何控制时间戳的格式。

unit=foo.service

ts=$(systemctl show -p ActiveEnterTimestamp $unit)

echo $ts
ActiveEnterTimestamp=Fri 2016-11-11 12:30:01 MST

journalctl -u $unit --since "$(echo $ts | awk '{print $2 $3}')"

答案3

您可以使用启动标志来仅获取该次启动的日志。例如

journalctl _SYSTEMD_UNIT=avahi-daemon.service -b 5

答案4

您可以将字段过滤器与 Journalctl 结合使用。例如

journalctl _PID=1234

使用以下方法获取所有可用字段的列表:

journalctl --fields --unit kubelet

一个可用字段是_PID

pidof您可以使用或获取正在运行的进程的 PIDsystemctl show --property MainPID <SERVICE_NAME>

以下是我从当前 Kubernetes kubelet 进程获取日志的方法:

# journalctl --unit kubelet _PID=$(systemctl show --property MainPID kubelet 2>/dev/null | cut -d= -f2) | head

现在告诉我为什么 Kubernetes 如此难安装 :-(

相关内容