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

Output Formats

 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

Configure Retention

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

TaskCommand
Follow logsjournalctl -f
Service logsjournalctl -u service
Since timejournalctl --since "1 hour ago"
Errors onlyjournalctl -p err
This bootjournalctl -b
Kerneljournalctl -k
Reverse orderjournalctl -r
Last N linesjournalctl -n 50
JSON outputjournalctl -o json
Disk usagejournalctl --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.