在调试无法加载的服务时,人们希望执行的一项常见任务是查看上次启动服务时的所有日志。
例如,给定
Jul 25 08:18:20 raspberrypi ngrok[3105]: Incorrect Usage: flag provided but not defined: -log
Jul 25 08:20:04 raspberrypi systemd[1]: [email protected] holdoff time over, scheduling restart.
Jul 25 08:20:04 raspberrypi systemd[1]: Stopping Share local port(s) with ngrok...
Jul 25 08:20:04 raspberrypi systemd[1]: Starting Share local port(s) with ngrok...
Jul 25 08:20:04 raspberrypi systemd[1]: Started Share local port(s) with ngrok.
Jul 25 08:20:04 raspberrypi ngrok[5474]: t=2016-07-25T08:20:04+0000 lvl=warn msg="failed to get home directory, using $HOME instead" err="user: Current not implemented on linux/arm" $HOME=
Jul 25 08:20:04 raspberrypi ngrok[5474]: Failed to open log file '/dev/stdout': open /dev/stdout: no such device or address
我想查看自 以来的所有线路Jul 25 08:20:04 raspberrypi systemd[1]: Starting Share local port...
。
类似于journalctl --boot
,但从上次服务启动时开始。
那可能吗?
同样,类似--list-boots
列出 systemctl 启动或停止服务的所有时间的内容将允许我模仿journalctl --last-start -u svc
我想要的行为。
答案1
不幸的是,目前不支持此功能。看https://github.com/systemd/systemd/issues/1942
GitHub 用户狼夫 发布了一个脚本在那个非常接近的问题中:
#!/bin/bash
#
[ "${FLOCKER}" != "$0" ] && exec env FLOCKER="$0" flock -en "$0" "$0" "$@" || :
# Timestamp when unit transitioned from inactive to active
since=$(systemctl show -p InactiveExitTimestamp "$1" | cut -f 2 -d '=' | cut -f 2-3 -d' ')
# or one minute if unset
since=${since:-1 min ago}
# Get prefix string that this units logs with: most robust
# https://github.com/systemd/systemd/issues/2913#issuecomment-219702148
id=$(systemctl show -p SyslogIdentifier "$1" | cut -f 2 -d '=')
# Get all raw output from unit since start, only from stdout&stderr
# Considering that backend only logs "bad" stack traces to stderr, this should
# always be relevant
service_trace=$(journalctl -o cat --since "$since" -t "$id")
答案2
下列的这个答案,从 systemd 232 开始你可以使用 systemd 的INVOCATION_ID
,这是特定的 ID跑步的一项服务。这就是我使用的:
function last_log() {
if [ $# == 1 ] then
echo -e "\nSyntax: $0 SERVICE_NAME"
exit 1
fi
ID=$(systemctl show -p InvocationID --value $1)
journalctl INVOCATION_ID=$ID + _SYSTEMD_INVOCATION_ID=$ID
}
请注意,提供无效的服务名称会导致行为不一致,并且您将失去命令行完成的好处。
答案3
获取上次服务启动日志的最简单方法不是journalctl而是systemctl status:例如
sudo systemctl status --no-pager -l -n 99999 svc
您还可以为journalctl指定一个开始时间,例如提前1小时:
sudo journalctl --no-pager --since='-1h' -u svc
或从特定时间开始:--since='16:00'
。