systemd’s journal collects logs from all services, the kernel, and system messages in one place. journalctl is your tool for searching, filtering, and following those logs.
Basic Usage#
1
2
3
4
5
6
7
8
9
10
11
| # Show all logs (oldest first)
journalctl
# Show all logs (newest first)
journalctl -r
# Follow new entries (like tail -f)
journalctl -f
# Show only errors and above
journalctl -p err
|
Filter by Time#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # Since boot
journalctl -b
# Previous boot
journalctl -b -1
# Since specific time
journalctl --since "2024-02-25 10:00:00"
# Until specific time
journalctl --until "2024-02-25 12:00:00"
# Time range
journalctl --since "1 hour ago"
journalctl --since "2024-02-25" --until "2024-02-26"
# Relative times
journalctl --since "yesterday"
journalctl --since "10 minutes ago"
|
Filter by Unit (Service)#
1
2
3
4
5
6
7
8
9
10
11
| # Specific service
journalctl -u nginx
# Multiple services
journalctl -u nginx -u php-fpm
# Follow specific service
journalctl -u nginx -f
# Service since boot
journalctl -u nginx -b
|
Filter by Priority#
Priority levels (0=emergency to 7=debug):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| journalctl -p emerg # 0 - System unusable
journalctl -p alert # 1 - Immediate action needed
journalctl -p crit # 2 - Critical conditions
journalctl -p err # 3 - Error conditions
journalctl -p warning # 4 - Warning conditions
journalctl -p notice # 5 - Normal but significant
journalctl -p info # 6 - Informational
journalctl -p debug # 7 - Debug messages
# Range (err and above)
journalctl -p err
# Specific range
journalctl -p warning..err
|
Filter by Other Criteria#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # By process ID
journalctl _PID=1234
# By user ID
journalctl _UID=1000
# By executable path
journalctl _EXE=/usr/bin/nginx
# By hostname
journalctl _HOSTNAME=webserver
# By transport
journalctl _TRANSPORT=kernel # Kernel messages
journalctl _TRANSPORT=syslog # Syslog messages
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Short (default)
journalctl -o short
# With microseconds
journalctl -o short-precise
# JSON (for parsing)
journalctl -o json
journalctl -o json-pretty
# Verbose (all fields)
journalctl -o verbose
# Only message
journalctl -o cat
# Export format (for sharing)
journalctl -o export
|
Combining Filters#
Filters are AND’d together:
1
2
3
4
5
6
7
8
| # nginx errors since yesterday
journalctl -u nginx -p err --since yesterday
# SSH logins in last hour
journalctl -u sshd --since "1 hour ago" | grep -i "accepted"
# Kernel errors this boot
journalctl -k -p err -b
|
Kernel Messages#
1
2
3
4
5
6
7
8
| # Kernel messages only
journalctl -k
# Kernel messages this boot
journalctl -k -b
# Follow kernel messages
journalctl -k -f
|
Disk Usage#
1
2
3
4
5
6
7
8
9
10
11
| # Show journal disk usage
journalctl --disk-usage
# Vacuum by size (keep 500MB)
sudo journalctl --vacuum-size=500M
# Vacuum by time (keep 2 weeks)
sudo journalctl --vacuum-time=2weeks
# Vacuum by files (keep 5 files)
sudo journalctl --vacuum-files=5
|
Practical Examples#
Debug Service Failures#
1
2
3
4
5
6
7
8
9
10
| # Why did service fail?
systemctl status nginx
journalctl -u nginx -n 50 --no-pager
# Show logs around last failure
journalctl -u nginx -p err -b
# Follow during restart
journalctl -u nginx -f &
systemctl restart nginx
|
Find Boot Problems#
1
2
3
4
5
6
7
8
| # Errors during current boot
journalctl -b -p err
# Errors during previous boot
journalctl -b -1 -p err
# List available boots
journalctl --list-boots
|
Monitor Live System#
1
2
3
4
5
6
7
8
| # All logs, following
journalctl -f
# Only errors, following
journalctl -f -p err
# Specific service, following
journalctl -u myapp -f
|
Search Logs#
1
2
3
4
5
6
7
8
9
10
11
| # grep for pattern
journalctl | grep "error"
# grep with context
journalctl | grep -C 3 "segfault"
# Case insensitive
journalctl | grep -i "failed"
# Multiple patterns
journalctl | grep -E "error|failed|timeout"
|
Export for Analysis#
1
2
3
4
5
6
7
8
9
| # Export to file
journalctl -u nginx --since today > nginx-today.log
# JSON for processing
journalctl -u nginx -o json > nginx.json
# Count errors per hour
journalctl -u nginx -p err --since today -o short | \
cut -d' ' -f1-2 | cut -d: -f1 | uniq -c
|
Check Authentication#
1
2
3
4
5
6
7
8
| # SSH login attempts
journalctl -u sshd | grep -i "accepted\|failed"
# sudo usage
journalctl _COMM=sudo
# su usage
journalctl _COMM=su
|
Container/Service Logs#
1
2
3
4
5
6
7
8
| # Docker containers (if using systemd)
journalctl -u docker
# Specific container
journalctl CONTAINER_NAME=myapp
# Podman
journalctl -u podman
|
Configuration#
Persistent Logs#
By default, logs may be in /run/log/journal (volatile). For persistence:
1
2
3
4
5
6
| # Check if persistent
ls /var/log/journal
# Enable persistence
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
|
Edit /etc/systemd/journald.conf:
1
2
3
4
| [Journal]
SystemMaxUse=500M
SystemMaxFileSize=50M
MaxRetentionSec=1month
|
Then restart:
1
| sudo systemctl restart systemd-journald
|
Cursor and Pagination#
1
2
3
4
5
6
7
8
9
10
11
12
| # Show cursor (for resuming)
journalctl --show-cursor
# Resume from cursor
journalctl --cursor "s=..."
# After cursor
journalctl --after-cursor "s=..."
# Limit output
journalctl -n 100 # Last 100 lines
journalctl -n 100 --no-pager # Without pager
|
Quick Reference#
| Task | Command |
|---|
| Follow logs | journalctl -f |
| Service logs | journalctl -u service |
| Since time | journalctl --since "1 hour ago" |
| Errors only | journalctl -p err |
| This boot | journalctl -b |
| Kernel | journalctl -k |
| Reverse order | journalctl -r |
| Last N lines | journalctl -n 50 |
| JSON output | journalctl -o json |
| Disk usage | journalctl --disk-usage |
journalctl replaces hunting through /var/log/* with a unified interface. The key filters are -u for services, -p for priority, -b for boot, and --since/--until for time ranges. Combine them to pinpoint exactly what you need without reading through gigabytes of logs.