Any user can read their own logs; reading the full system journal needs or membership in the or group. Filters combine, so is one valid command.
Service Logs
| Command | What it does |
|---|---|
| Every log line from the nginx unit, oldest first | |
| Open the pager at the end, newest lines on screen | |
| Two units interleaved in time order (repeat for more) | |
| Units matching a pattern | |
| Jump to the end with catalog explanations, what tells you to run after a failure | |
| A user service, no sudo needed | |
| Follow kubelet on a Kubernetes node, the first stop when a node goes NotReady | |
| The whole journal, every unit and the kernel |
shows nothing for a misspelled unit name rather than erroring; confirm the name with from the systemctl cheat sheet.
Follow and Tail
| Command | What it does |
|---|---|
| Follow live, like (Ctrl+C stops) | |
| Last 100 lines ( alone means 10) | |
| Same, straight to the terminal for copy-paste | |
| Follow but start empty, only new lines | |
| Newest first | |
| Follow everything, all units at once |
Time Ranges
and take human phrases and absolute stamps, and stack with every other filter.
| Command | What it does |
|---|---|
| The last hour | |
| Since midnight ( covers all of yesterday) | |
| Since midnight at the start of that date | |
| A precise window | |
| The last 30 minutes, shorthand | |
| Exclude the most recent lines | |
| Interpret and print times in UTC instead of local |
Boots
Crash forensics live here: limits output to one boot, counted backwards from the current one.
| Command | What it does |
|---|---|
| Only the current boot | |
| The previous boot, the one that crashed or was rebooted away | |
| Every boot the journal knows, with index and time span | |
| End of the previous boot, the last thing logged before it went down | |
| Everything at error level or worse from the previous boot | |
| Kernel messages from the previous boot (OOM kills, panics, disk errors) |
After an unexplained reboot, this sequence usually finds the cause:
journalctl --list-boots
journalctl -b -1 -e
journalctl -b -1 -p err -o short-iso
journalctl -b -1 -k -g "oom|panic|error"If shows only one boot, the journal is volatile and pre-reboot logs are gone; see the persistence setup under Disk Usage below.
Priority
| Command | What it does |
|---|---|
| Priority and worse | |
| One unit, and worse | |
| Only a range of levels | |
| Numbers work too (3 is ) |
| Level | Name | Typical meaning |
|---|---|---|
| 0 | System is unusable | |
| 1 | Act immediately | |
| 2 | Critical condition | |
| 3 | Error | |
| 4 | Something to look at | |
| 5 | Normal but notable | |
| 6 | Routine | |
| 7 | Debug detail |
means 0 through 3, not just 3: a priority flag always includes everything worse than the level named.
Search and Filter
| Command | What it does |
|---|---|
| Grep the messages (PCRE; case-insensitive when the pattern is all lowercase) | |
| Grep within one unit | |
| Kernel messages only, the equivalent with timestamps and history | |
| Everything logged by one process ID | |
| Everything logged by one user's processes | |
| Everything logged by one executable | |
| Same idea, matched by process name | |
| Plain grep still works when is missing (systemd older than 239) |
Field filters like combine with , and time flags like any other filter. shows every field a journal entry carries, which is how you discover what to filter on.
Output Formats
| Command | What it does |
|---|---|
| ISO 8601 timestamps, sortable and unambiguous | |
| Microsecond timestamps | |
| One JSON object per line, for and log shippers | |
| Readable JSON, one entry at a time | |
| Message text only, no timestamps or hostnames | |
| Print times in UTC | |
| Append the cursor of the last entry shown | |
| Resume from a saved cursor | |
| Read the cursor from a file and update it after, for polling scripts |
Cursors give a script an exact resume point, so a cron job can process only what arrived since its last run without overlaps or gaps.
Disk Usage and Vacuum
| Command | What it does |
|---|---|
| Total space the journal takes on disk | |
| Delete oldest archived files until under 500 MB | |
| Delete everything older than two weeks | |
| Keep only the five newest journal files | |
| Archive the active file so vacuum can reach it | |
| Check journal files for corruption |
Vacuum only removes archived files, so first when you need space back now. To cap size permanently and keep logs across reboots, set both in :
[Journal]
Storage=persistent
SystemMaxUse=500Msudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journaldThe edge case that bites: the default persists only if already exists. Debian and Ubuntu ship the directory, so their logs survive reboots; RHEL and CentOS generally do not, so every boot starts the journal empty and has nothing to show until you create it.
Gotchas
- Empty output from usually means a misspelled or different unit name, not missing logs. settles it.
- erroring with no persistent journal means the logs you want are already gone. Set up persistence today, before the crash you will want to debug.
- shows and everything worse, and it filters on the priority the service declared. Apps that write plain text to stdout log everything at , so their errors do not surface under ; use for those.
- Timestamps print in the machine's local timezone. On servers set to UTC that is what you expect; on anything else, avoids an hour of confusion during incident timelines.
- needs systemd 239 or newer. Older hosts (CentOS 7 and friends) pipe to instead.
- Without you see your own logs only, and journalctl says so in a hint at the top that is easy to scroll past. Add yourself to for read access without sudo.
- The journal and a service's own log files are separate worlds. nginx access logs live in , not the journal; the journal has stdout, stderr and what systemd itself says about the unit. The systemctl cheat sheet covers the service side.