journald, rsyslog, and /var/log
Where logs actually live, and the fastest path to the relevant line. · 10 min
On modern systemd-based systems, `journald` captures logs centrally in a binary format, queried through `journalctl` — this includes systemd's own messages, kernel messages, and anything a service run under systemd writes to standard output or error. Many traditional services also still write plain-text logs directly to files under `/var/log` (`/var/log/nginx/error.log`, `/var/log/auth.log` or `/var/log/secure` for authentication attempts) — some distributions configure `rsyslog` to also mirror journald content into these traditional flat files for compatibility with older tooling and habits.
The fastest, most targeted path to a relevant log line: `journalctl -u <service>` scopes to one service instead of the entire system journal. `journalctl --since "10 minutes ago"` (or `--since "2026-09-19 14:00" --until "2026-09-19 14:15"`) scopes by time — essential when you know roughly when an incident happened and don't want to wade through unrelated noise. `journalctl -p err` filters to error-priority-and-above messages only. `journalctl -f` follows new entries live, the systemd equivalent of `tail -f`.
For plain-text logs under `/var/log`, `tail -f /var/log/nginx/error.log` follows a specific file live, and `grep` narrows a large log file to lines matching a pattern — `grep -i "error" /var/log/syslog | tail -50` is a common, genuinely useful combination for a first pass over a noisy log.
| Command | Purpose | Example |
|---|---|---|
| journalctl -u name | View logs for a specific systemd service | — |
| journalctl -f | Follow the journal live | — |
| journalctl --since "1 hour ago" | Scope logs to a relative or absolute time window | — |
| journalctl -p err | Show only error-priority-and-above entries | — |
| tail -f /var/log/file | Follow a plain-text log file live | — |
| grep -i pattern file | Search a log file, case-insensitive | grep -i "failed" /var/log/auth.log |
Hands-On Lab
Troubleshoot a failed service using logs alone
Objectives
- ✓ Intentionally break a service's configuration
- ✓ Diagnose the cause purely from journalctl output, without guessing
- ✓ Fix it and confirm via the logs that it's resolved
Instructions
- Install nginx (`sudo apt install nginx`) and confirm it's running with `systemctl status nginx`.
- Introduce a deliberate syntax error into `/etc/nginx/nginx.conf` (e.g. remove a closing brace) and attempt `sudo systemctl restart nginx`.
- Notice the restart fails — run `sudo journalctl -u nginx --since "5 minutes ago"` and read the actual error nginx reported, rather than guessing.
- Fix the syntax error based on what the log actually said, then restart and confirm success both via `systemctl status` and by seeing no new errors in `journalctl -u nginx`.
Hints (1)
- nginx also has its own dedicated error log at `/var/log/nginx/error.log`, which can carry more detail than the systemd journal alone — check both when journalctl output seems incomplete.
Takeaway: `journalctl -u <service> --since "recent time window"` is the fastest path to the actual cause of a service failure — narrow by service and time before reading anything, instead of scrolling through the entire system log.