journalctl: Filter and Search System Logs (2026 Guide)
Last updated: March 2026
journalctl is the command-line tool for reading logs collected by systemd's journald. Every service managed by systemd writes its stdout and stderr to the journal automatically — no log file configuration needed. journald also collects kernel messages, boot logs, and audit records in one unified, binary-indexed store. This guide covers every important filter, output format, and maintenance command.
Basic Usage
# Show all journal entries (opens in a pager like less)
journalctl
# Disable the pager and print all output
journalctl --no-pager
# Show the most recent entries first (reverse order)
journalctl -r
# Last 50 lines
journalctl -n 50
# Follow live output (like tail -f)
journalctl -f
By default, journalctl opens logs in less. Navigation keys:
- G — jump to end
- g — jump to beginning
- /pattern — search forward
- ?pattern — search backward
- q — quit
Filter by Unit (-u)
The most common filter: show logs for a specific service.
# All logs for a unit
journalctl -u nginx
journalctl -u sshd
journalctl -u myapp.service
# Follow live
journalctl -u nginx -f
# Last 100 lines
journalctl -u nginx -n 100
# Multiple units
journalctl -u nginx -u php-fpm
For services you manage directly, see the systemd service file guide on how to ensure logs go to journald.
Filter by Time (--since / --until)
Absolute timestamps
journalctl --since "2026-03-26"
journalctl --since "2026-03-26 10:00:00"
journalctl --until "2026-03-26 12:00:00"
# Time range
journalctl --since "2026-03-26 10:00:00" --until "2026-03-26 11:30:00"
Timestamp format: YYYY-MM-DD HH:MM:SS. The time portion is optional.
Relative timestamps
journalctl --since "1 hour ago"
journalctl --since "30 minutes ago"
journalctl --since "2 days ago"
journalctl --since yesterday
journalctl --since today
Combined with unit filter
journalctl -u nginx --since "1 hour ago"
journalctl -u postgresql --since "2026-03-25" --until "2026-03-26"
Filter by Priority (-p)
journald uses syslog priority levels 0–7:
| Number | Name | Meaning |
|---|---|---|
| 0 | emerg |
System unusable |
| 1 | alert |
Action must be taken immediately |
| 2 | crit |
Critical conditions |
| 3 | err |
Error conditions |
| 4 | warning |
Warning conditions |
| 5 | notice |
Normal but significant |
| 6 | info |
Informational |
| 7 | debug |
Debug-level messages |
# Show errors and above (0, 1, 2, 3)
journalctl -p err
journalctl -p 3
# Show warnings and above (0-4)
journalctl -p warning
# Priority range: warnings through errors only
journalctl -p warning..err
# Show only info messages
journalctl -p info -p info # exact level (not range)
Combine with unit:
journalctl -u nginx -p err --since "1 hour ago"
Filter by Boot (-b)
# Current boot
journalctl -b
journalctl -b 0 # same as above
# Previous boot
journalctl -b -1
# Two boots ago
journalctl -b -2
# List available boots
journalctl --list-boots
--list-boots output:
-2 a1b2c3d4... Mon 2026-03-24 08:00:00 UTC—Mon 2026-03-24 18:00:00 UTC
-1 e5f6a7b8... Tue 2026-03-25 09:00:00 UTC—Tue 2026-03-25 20:00:00 UTC
0 c9d0e1f2... Wed 2026-03-26 08:30:00 UTC—Wed 2026-03-26 10:00:00 UTC
Combine with unit to see why a service was failing after last reboot:
journalctl -u myapp -b -1
Kernel Messages (-k)
# All kernel messages (equivalent to dmesg)
journalctl -k
# Kernel messages since last boot
journalctl -k -b
# Recent kernel messages, follow
journalctl -k -f
# Kernel errors
journalctl -k -p err
Useful for diagnosing hardware issues, driver errors, OOM kills, and filesystem errors.
Output Formats (-o)
| Format | Description |
|---|---|
short |
Default. Timestamp, hostname, unit, message |
short-precise |
Like short but with microsecond precision |
short-iso |
ISO 8601 timestamps |
short-monotonic |
Monotonic timestamps (seconds since boot) |
verbose |
All metadata fields |
json |
One JSON object per line |
json-pretty |
Multi-line indented JSON |
cat |
Message text only (no metadata) |
export |
Binary export format |
# JSON output (useful for log processing with jq)
journalctl -u nginx -o json | jq '.MESSAGE'
# Pretty JSON for readability
journalctl -u myapp -n 5 -o json-pretty
# Just the message text, no timestamps
journalctl -u myapp -o cat
# Verbose: all fields
journalctl -u sshd -n 1 -o verbose
Processing with jq
# Extract specific fields
journalctl -u nginx -o json --no-pager | jq '{time: .__REALTIME_TIMESTAMP, msg: .MESSAGE}'
# Filter by message content
journalctl -u nginx -o json --no-pager | jq 'select(.MESSAGE | contains("error"))'
# Count errors per hour
journalctl -u myapp -o json --no-pager --since "24 hours ago" \
| jq -r '.SYSLOG_TIMESTAMP' | cut -c1-14 | sort | uniq -c
Adding Timestamps (--timestamps)
When following logs, timestamps are shown by default. For piped output, they may be suppressed:
journalctl -u myapp -f --output=short-precise
Filtering by Field
journald stores structured fields. You can filter by any of them:
# Filter by systemd unit (same as -u)
journalctl _SYSTEMD_UNIT=nginx.service
# Filter by PID
journalctl _PID=1234
# Filter by executable path
journalctl _EXE=/usr/sbin/sshd
# Filter by user ID
journalctl _UID=1000
# Filter by hostname (useful in centralized logging)
journalctl _HOSTNAME=webserver1
# Container logs (if using systemd-nspawn or similar)
journalctl CONTAINER_NAME=mycontainer
Persistent Logs
By default, on many distributions journald stores logs only in memory (/run/log/journal/) and they are lost on reboot. To keep logs across reboots, enable persistent storage.
Enable persistence
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
Or set it in the journald configuration:
sudo nano /etc/systemd/journald.conf
Set:
[Journal]
Storage=persistent
Then restart:
sudo systemctl restart systemd-journald
With persistent storage, logs are written to /var/log/journal/ and retained across reboots. The journalctl -b -1 (previous boot) command only works if logs are persistent.
Verify storage mode
journalctl --disk-usage
# Archived and active journals take up 512.0M on disk.
ls /var/log/journal/
Disk Usage and Log Rotation
Check disk usage
journalctl --disk-usage
Limit log retention
Set limits in /etc/systemd/journald.conf:
[Journal]
Storage=persistent
# Keep at most 1 GB
SystemMaxUse=1G
# Always keep at least 100 MB free
SystemKeepFree=100M
# Maximum size of a single journal file
SystemMaxFileSize=50M
# Maximum age of journal files
MaxRetentionSec=1month
Restart journald after editing:
sudo systemctl restart systemd-journald
Vacuum (manual cleanup)
# Reduce to 500 MB total
sudo journalctl --vacuum-size=500M
# Remove entries older than 30 days
sudo journalctl --vacuum-time=30d
# Keep at most 5 journal files
sudo journalctl --vacuum-files=5
These commands remove archived (rotated) journal files. They do not touch the active journal file.
Useful One-Liners
# See all failed services
journalctl -p err -b --no-pager | grep "Failed"
# Find OOM kills
journalctl -k --no-pager | grep -i "out of memory\|oom"
# SSH authentication failures
journalctl -u sshd --no-pager | grep "Failed password\|Invalid user"
# All logs from the last 5 minutes
journalctl --since "5 minutes ago" --no-pager
# Export logs to a file
journalctl -u myapp --since "2026-03-25" --until "2026-03-26" --no-pager > myapp.log
# Show logs from all units that mention a specific string
journalctl --grep="connection refused" --since "1 hour ago"
FAQ
Q: journalctl shows "No entries" or very few entries. Why?
Logs may not be persistent. Check journalctl --disk-usage. If it shows /run/log/journal/ (not /var/log/journal/), persistence is not enabled. See the "Persistent Logs" section above.
Q: How do I search for a specific string in logs?
journalctl --grep="pattern"
# Or pipe to grep
journalctl -u myapp --no-pager | grep "ERROR"
# Case-insensitive
journalctl --grep="error" --case-sensitive=false
Q: Can I send application logs to journald without systemd managing the process?
Yes. Use systemd-cat:
echo "Manual log entry" | systemd-cat -t myapp -p info
# Or pipe a command's output
/usr/local/bin/myscript.sh | systemd-cat -t myscript
Or write directly to the journal socket using the sd_journal_print() C API or its Python binding systemd.journal.