journalctl in Practice - Filtering Logs from the systemd Journal

journalctl in Practice - Filtering Logs from the systemd Journal

What You Can Solve with This Article

journalctl is the systemd log query tool. With the right filter combinations, you can extract specific lines from millions of log entries in seconds. The patterns below cover the majority of real-world log investigation tasks.

Most-used combinations (copy-paste ready)

# nginx errors in the last hour
journalctl -u nginx -p err --since "1 hour ago"

# All errors since current boot
journalctl -b -p err

# Follow a unit in real time
journalctl -u myapp.service -f

How to filter by unit

Use -u to scope output to a specific service. This is the most-used option in practice.

# Single unit
journalctl -u nginx.service

# Multiple units at once
journalctl -u nginx.service -u php-fpm.service

The .service suffix can be omitted — -u nginx works too.

How to specify a time range

Use --since and --until to narrow by time. Both relative and absolute formats are accepted.

# Last hour
journalctl --since "1 hour ago"

# Last 30 minutes
journalctl --since "30 min ago"

# From a specific timestamp to now
journalctl --since "2026-05-30 14:00:00"

# Bounded range
journalctl --since "2026-05-30 10:00" --until "2026-05-30 12:00"

-S is shorthand for --since, -U for --until. The long forms are more readable in scripts.

How to show only errors

-p filters by syslog priority. Specifying a level shows that level and above (more severe).

# err and above (err, crit, alert, emerg)
journalctl -p err

# warning and above
journalctl -p warning

# Exact level only (range syntax)
journalctl -p err..err
Number Keyword Meaning
0 emerg System is unusable
1 alert Immediate action required
2 crit Critical condition
3 err Error
4 warning Warning
5 notice Normal but significant
6 info Informational
7 debug Debug messages

How to follow logs in real time

-f is the equivalent of tail -f. New log entries appear as they arrive.

# Watch a unit after deploying
journalctl -u myapp.service -f

# Follow errors only
journalctl -u myapp.service -p err -f

Press Ctrl+C to stop. Use -n to start from the last N lines.

# Start from last 50 lines, then follow
journalctl -u nginx -n 50 -f

How to filter by boot

-b shows logs for the current boot only. Use --list-boots to see past boots before narrowing to a specific one.

# Current boot
journalctl -b

# List all past boots with their IDs
journalctl --list-boots

# Previous boot
journalctl -b -1

# Two boots ago
journalctl -b -2
-3 d7a3f8...  Mon 2026-05-27 09:00 UTC—Mon 2026-05-27 18:30 UTC
-2 a1b2c3...  Tue 2026-05-28 08:45 UTC—Tue 2026-05-28 20:00 UTC
-1 e5f6a7...  Wed 2026-05-29 09:10 UTC—Wed 2026-05-29 23:45 UTC
 0 b8c9d0...  Thu 2026-05-30 08:00 UTC—present

How to filter by field or process

journalctl accepts direct field key-value pairs as filters. See man systemd.journal-fields for the complete list.

# By PID
journalctl _PID=12345

# By command name
journalctl _COMM=sshd

# By syslog identifier
journalctl SYSLOG_IDENTIFIER=nginx

# Logs from a specific user's processes
journalctl _UID=1000

journalctl -F _COMM lists all values present in the journal for the _COMM field. Useful when you are not sure which identifiers exist.

How to combine with grep

Use the built-in --grep option (v233+) or pipe to grep.

# Built-in grep
journalctl -u nginx --grep "error"

# Regex pattern
journalctl -u nginx --grep "5[0-9][0-9]"

# Pipe to grep
journalctl -u nginx | grep -i "connection refused"

# Combine time range and grep
journalctl --since "2 hours ago" | grep "ERROR"

--grep only searches the MESSAGE field. Pipe to grep when you need to search across all fields.

How to change output format

-o controls the output format. Useful for log analysis and tool integration.

# JSON (one log entry per line)
journalctl -u nginx -o json

# Pretty-printed JSON
journalctl -u nginx -o json-pretty

# Short timestamp format
journalctl -o short

# Message only (no metadata)
journalctl -o cat

JSON output works well with jq for further processing.

# Extract timestamp and message from errors
journalctl -u nginx -p err -o json | jq -r '.__REALTIME_TIMESTAMP + " " + .MESSAGE'

Without --no-pager, journalctl opens in a pager (like less). Always add it in scripts.

journalctl -u nginx --no-pager | wc -l

Summary: Quick Reference Table

Filters can be combined freely. The standard starting point in practice is to scope by unit with -u, then narrow to errors with -p err.

Goal Command
Filter by unit journalctl -u nginx
Time range journalctl --since "1 hour ago"
Errors only journalctl -p err
Current boot journalctl -b
Follow journalctl -f
Filter by PID journalctl _PID=1234
Combine with grep journalctl -u nginx --grep "error"
JSON output journalctl -o json
Disable pager journalctl --no-pager
# Common real-world combinations
journalctl -u nginx.service -p err --since "today" --no-pager

journalctl -b -p warning -u ssh.service -f

Next Reading