Is there a way to make journalctl show logs from "the last time foo.service ran"?
Solution 1:
I'm not sure which timestamp makes the most sense but this works for me. Hopefully there is a better way of working with the timestamps from systemctl show
than awk - could not figure out how to control the format of timestamps.
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}')"
Solution 2:
Since systemd
version 232
, we have the concept of invocation ID. Each time a unit is ran, it has a unique 128 bit invocation ID. Unlike MainPID
which can be recycled, or ActiveEnterTimestamp
which can have resolution troubles, it is a failsafe way to get all the log of a particular systemd unit invocation.
To obtain the latest invocation ID of a unit
$ systemctl show --value -p InvocationID openipmi
bd3eb84c3aa74169a3dcad2af183885b
To obtain the journal of the latest invocation of, say, openipmi
, whether it failed or not, you can use the one liner
$ 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.
(Note that the --value
is available since systemd 230
, older than InvocationID
)
Solution 3:
You can use the boot flag to fetch only the logs from that boot. for instance
journalctl _SYSTEMD_UNIT=avahi-daemon.service -b 5
Solution 4:
These might help you:
journalctl -u foo.service | tail -n 2
or replace 2 with expected number of lines
journalctl -u foo.service --since='2016-04-11 13:00:00'
You can as well combine them to get firstly the last run time timestamp, and then use that timestamp with the --since switch.
Solution 5:
You can use field filters with Journalctl. E.g.
journalctl _PID=1234
Get a list of all the available fields using:
journalctl --fields --unit kubelet
One available field is _PID
.
You can get the PID of a running process using pidof
or systemctl show --property MainPID <SERVICE_NAME>
So here's how I get the logs from the current Kubernetes kubelet process:
# journalctl --unit kubelet _PID=$(systemctl show --property MainPID kubelet 2>/dev/null | cut -d= -f2) | head
Now tell me why I Kubernetes is so hard to install :-(