我对此特别感兴趣,因为我可以查看在计时器上运行的一次性服务的输出。该--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 show
awk 更好的方法来处理时间戳 - 无法弄清楚如何控制时间戳的格式。
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 如此难安装 :-(