When a Linux computer behaves oddly, the answer is almost always written down somewhere. The trouble is that there are thousands of messages and, without filters, finding the right one is like reading a phone book. On a modern system there are two main tools: journalctl, which queries the systemd journal, and dmesg, which shows kernel messages. A handful of options is enough to get to the point in seconds.
Where messages end up
On distributions that use systemd, every message, from the kernel to the services, is collected by journald into a binary, indexed journal. Many distributions still run rsyslog alongside it, which writes text files in /var/log/, such as syslog on Debian and Ubuntu or messages on Fedora and its derivatives. Some programs also keep their own logs: the web server in /var/log/nginx/, the package manager in /var/log/apt/ or /var/log/dnf.log.
The journald journal can be volatile, kept only in memory and lost at every reboot, or persistent on disk in /var/log/journal/. If journalctl --list-boots shows only one boot, the journal is not being kept: just create the /var/log/journal folder and restart the systemd-journald service, or set Storage=persistent in /etc/systemd/journald.conf.
journalctl: the options you actually need
Run on its own, journalctl shows everything from oldest to newest, opened in a pager where you scroll with the arrow keys and search with /. The useful options are few:
| Option | Effect |
|---|---|
-b |
current boot only; -b -1 the previous one |
-u name |
messages from one service only |
-p err |
errors and more severe levels only |
-f |
follows new messages live, like tail -f |
-e |
jumps straight to the end |
-n 50 |
shows only the last 50 lines |
--since, --until |
limits to a time range |
-k |
kernel messages only |
The options can be combined. For example, errors from the SSH service in the last hour:
journalctl -u ssh -p err --since "1 hour ago"
Or everything that happened yesterday afternoon between 3 and 4 pm:
journalctl --since "yesterday 15:00" --until "yesterday 16:00"
Priorities
Every message has a severity level inherited from the syslog tradition. From most to least severe: emerg, alert, crit, err, warning, notice, info, debug. With -p warning you see warnings and everything more severe. In the pager, errors appear in red.
dmesg: kernel messages
dmesg reads the kernel's ring buffer: device detection, drivers loading, disk errors, memory running out. On many distributions it needs sudo. The handiest options:
dmesg -Tshows readable timestamps instead of seconds since boot;dmesg -wfollows new messages live;dmesg --level=err,warnfilters by severity.
A typical use: you plug in a USB stick that doesn't show up. With sudo dmesg -w open in a terminal, you plug it in and immediately see whether the kernel recognised it, under which device name, and possibly which error it returned.
What to look for in common cases
- A failing disk: lines with
I/O error,blk_update_requestor SATA link resets. Take them seriously and follow up with a check of the SMART values. - Out of memory: lines with
Out of memory: Killed processtell you which process the kernel sacrificed. Find them withjournalctl -k | grep -i "out of memory". - A service that won't start:
journalctl -u name -balmost always shows the exact message, for example a syntax error in the configuration file or a port already in use. - Sudden shutdowns: look at the end of the previous boot with
journalctl -b -1 -e. If the journal stops abruptly without the shutdown lines, the computer went off without an orderly command, as happens with a power cut or a power supply problem. - Login attempts: on an exposed server,
journalctl -u ssh | grep "Failed password"shows failed password login attempts.
How much space they take
The persistent journal grows but has automatic limits, by default a percentage of the filesystem's space. To see how much it uses:
journalctl --disk-usage
To shrink it right away you can keep only a certain period or size:
sudo journalctl --vacuum-time=30d
sudo journalctl --vacuum-size=500M
For a permanent limit, set SystemMaxUse= in journald.conf. The text files in /var/log are handled by logrotate, which rotates, compresses and deletes them according to the rules in /etc/logrotate.d/. Deleting logs by hand with rm while the service is writing them is a bad idea: the space may not be freed until the process reopens the file.
A method to avoid getting lost
In my work I always follow the same order: first I narrow down the time when the problem happened, then the service or device involved, and finally the severity. Three filters, combined, turn tens of thousands of lines into a few dozen. Only then do I read the messages one by one, starting from the first error rather than the last: later errors are often consequences of the first.
In short
- journald collects almost everything; rsyslog and individual programs may also write to
/var/log. journalctl -b,-u,-pand--sincenarrow the search straight away.dmesg -T -wis the right tool for devices, drivers and hardware problems.- Log space is checked with
--disk-usageand limited with--vacuumorSystemMaxUse. - Read starting from the first error in the relevant period, not the last.