How To

Filter Systemd Logs with journalctl (Practical Examples)

When something breaks at 3 AM, journalctl is the first command you reach for. It queries the systemd journal and lets you filter by service, time, priority, PID, or any combination of these. The structured binary format means you can slice logs in ways that plain text files and grep simply cannot match.

Original content from computingforgeeks.com - post 116857

This guide covers every practical journalctl filter you will use in day-to-day troubleshooting and monitoring. Each example was tested on a live Ubuntu 24.04 system with systemd 255. For setting up persistent journal storage and retention limits, see our persistent systemd journal configuration guide.

Tested March 2026 on Ubuntu 24.04 LTS with systemd 255 (255.4-1ubuntu8.1)

View Recent Log Entries

Show the last N log entries with -n. This is your go-to for a quick look at what just happened:

journalctl -n 10 --no-pager

The output shows the most recent 10 entries with timestamp, hostname, process, and message:

Mar 25 15:07:20 ubuntu systemd[1016]: Reached target basic.target - Basic System.
Mar 25 15:07:20 ubuntu systemd[1016]: Reached target default.target - Main User Target.
Mar 25 15:07:20 ubuntu systemd[1016]: Startup finished in 141ms.
Mar 25 15:07:20 ubuntu systemd[1]: Started [email protected] - User Manager for UID 1000.
Mar 25 15:07:20 ubuntu systemd[1]: Started session-1.scope - Session 1 of User ubuntu.

Show entries in reverse order (newest first) with -r:

journalctl -r -n 5 --no-pager

Follow Logs in Real Time

Watch new log entries as they appear, similar to tail -f:

journalctl -f

Combine with a service filter to watch only one service:

journalctl -fu ssh.service

Press Ctrl+C to stop following.

Filter by Service Unit

The -u flag filters logs for a specific systemd service. This is the most common filter for troubleshooting:

journalctl -u ssh.service --no-pager -n 8

The output shows only SSH-related messages:

Mar 25 15:07:18 ubuntu sshd[1009]: Server listening on :: port 22.
Mar 25 15:07:18 ubuntu systemd[1]: Started ssh.service - OpenBSD Secure Shell server.
Mar 25 15:07:18 ubuntu sshd[1010]: Connection closed by 129.222.187.73 port 32744
Mar 25 15:07:20 ubuntu sshd[1011]: Accepted publickey for ubuntu from 129.222.187.73 port 51497 ssh2
Mar 25 15:07:20 ubuntu sshd[1011]: pam_unix(sshd:session): session opened for user ubuntu(uid=1000)

Filter multiple services at once:

journalctl -u ssh.service -u nginx.service --no-pager -n 20

Note: service names vary between distros. Ubuntu 24.04 uses ssh.service while Rocky Linux uses sshd.service. Check your service name with systemctl list-units --type=service.

Filter by Time

Narrow logs to a specific time window with --since and --until. Both accept absolute timestamps and relative expressions.

Logs from the last hour:

journalctl --since "1 hour ago" --no-pager -n 20

Logs from today only:

journalctl --since today --no-pager -n 20

Logs between two specific timestamps:

journalctl --since "2026-03-25 15:06:00" --until "2026-03-25 15:07:30" --no-pager -n 10

The output shows only entries within that 90-second window:

Mar 25 15:07:22 ubuntu sshd[1011]: pam_unix(sshd:session): session closed for user ubuntu
Mar 25 15:07:22 ubuntu systemd-logind[758]: Session 1 logged out. Waiting for processes to exit.
Mar 25 15:07:22 ubuntu systemd[1]: session-1.scope: Deactivated successfully.
Mar 25 15:07:22 ubuntu systemd[1]: session-1.scope: Consumed 1.932s CPU time.

Logs from yesterday:

journalctl --since yesterday --until today --no-pager

Other relative expressions that work: "5 minutes ago", "2 hours ago", "3 days ago", yesterday, today, now.

Filter by Priority Level

Syslog priority levels range from 0 (emergency) to 7 (debug). The -p flag filters by priority, showing all entries at the specified level and above:

journalctl -p err --no-pager

This shows entries at err (3) and above, including crit, alert, and emerg. Available priority names:

LevelNameMeaning
0emergSystem is unusable
1alertImmediate action required
2critCritical conditions
3errError conditions
4warningWarning conditions
5noticeNormal but significant
6infoInformational messages
7debugDebug-level messages

Filter a specific priority range (e.g., only warnings):

journalctl -p warning..warning --no-pager -n 10

Filter by Boot

With persistent journal storage, you can query logs from previous boots. List all recorded boots:

journalctl --list-boots

Each boot has an index number (0 = current, -1 = previous) and a boot ID:

IDX BOOT ID                          FIRST ENTRY                 LAST ENTRY
  0 6bbaadfab85347a28818957bb54af405 Wed 2026-03-25 15:06:20 UTC Wed 2026-03-25 15:07:20 UTC

View logs from the current boot:

journalctl -b

View logs from the previous boot:

journalctl -b -1

Filter by Kernel Messages

The -k flag shows only kernel messages (equivalent to dmesg but with timestamps and filtering):

journalctl -k --no-pager -n 5

Kernel messages include hardware detection, driver loading, and filesystem events:

Mar 25 15:06:44 ubuntu kernel: kauditd_printk_skb: 103 callbacks suppressed
Mar 25 15:06:44 ubuntu kernel: loop0: detected capacity change from 0 to 8
Mar 25 15:06:44 ubuntu kernel: audit: type=1400 audit(1774451204.577:115): apparmor="STATUS" operation="profile_replace"

Filter by PID, UID, or GID

Filter logs from a specific process ID:

journalctl _PID=1009 --no-pager -n 5

Filter by user ID (all messages from root):

journalctl _UID=0 --no-pager -n 5

Find the PID of a running service first, then query its logs:

SSHD_PID=$(pgrep -o sshd)
journalctl _PID=$SSHD_PID --no-pager

Filter by executable path (all messages from the sshd binary):

journalctl _EXE=/usr/sbin/sshd --no-pager -n 5

Search with Pattern Matching

The -g flag (or --grep) searches message text using regular expressions. Find all SSH-related entries:

journalctl -g "ssh" --no-pager -n 5

Search for failed login attempts:

journalctl -g "Failed password|authentication failure" --no-pager

Case-insensitive search with --case-sensitive=no:

journalctl -g "error" --case-sensitive=no --no-pager -n 10

Output Formats

Journalctl supports multiple output formats via -o. The format you choose depends on whether you are reading logs manually or feeding them to a script.

FormatFlagUse Case
Default (short)-o shortHuman-readable, syslog style
ISO timestamps-o short-isoUnambiguous timestamps for log analysis
JSON (compact)-o jsonPiping to jq or scripts
JSON (pretty)-o json-prettyReadable structured data
Verbose-o verboseAll metadata fields for debugging
Message only-o catJust the message text, no metadata
Export-o exportBinary export for systemd-journal-remote

ISO timestamp format for clean log analysis:

journalctl -o short-iso -n 3 --no-pager
2026-03-25T15:07:20+00:00 ubuntu systemd[1016]: Startup finished in 141ms.
2026-03-25T15:07:20+00:00 ubuntu systemd[1]: Started [email protected] - User Manager for UID 1000.
2026-03-25T15:07:20+00:00 ubuntu systemd[1]: Started session-1.scope - Session 1 of User ubuntu.

JSON output with full structured metadata (useful for piping to jq):

journalctl -u ssh.service -n 1 -o json-pretty --no-pager

The JSON output includes every field the journal stores for that entry:

{
    "PRIORITY" : "6",
    "_UID" : "0",
    "_SYSTEMD_UNIT" : "ssh.service",
    "_EXE" : "/usr/sbin/sshd",
    "_PID" : "1218",
    "MESSAGE" : "pam_unix(sshd:session): session opened for user ubuntu(uid=1000)",
    "__REALTIME_TIMESTAMP" : "1774451258043395",
    "_HOSTNAME" : "test-ubuntu-24-computingforgeeks-com"
}

Verbose format shows all metadata fields for a single entry:

journalctl -u ssh.service -n 1 -o verbose --no-pager

This is the most detailed view available. Each field (PID, UID, executable path, cgroup, boot ID) appears on its own line:

Wed 2026-03-25 15:07:38.042876 UTC
    _BOOT_ID=6bbaadfab85347a28818957bb54af405
    _MACHINE_ID=c062bd9deb7c533216c9fa60191f76f3
    PRIORITY=6
    _UID=0
    _SYSTEMD_UNIT=ssh.service
    _EXE=/usr/sbin/sshd
    _PID=1218
    _CMDLINE="sshd: ubuntu [priv]"
    MESSAGE=pam_unix(sshd:session): session opened for user ubuntu(uid=1000)

Combine Filters

The real power of journalctl comes from combining filters. Each filter narrows the results further.

SSH errors in the last hour:

journalctl -u ssh.service -p err --since "1 hour ago" --no-pager

Kernel messages from the previous boot at warning level or above:

journalctl -k -b -1 -p warning --no-pager

All root user activity from yesterday, in JSON format:

journalctl _UID=0 --since yesterday --until today -o json --no-pager

Follow nginx logs at error priority only:

journalctl -fu nginx.service -p err

Disk Usage and Cleanup

Check how much disk space the journal uses:

journalctl --disk-usage

On a fresh system, this is typically small:

Archived and active journals take up 16.0M in the file system.

Remove journal entries older than 30 days:

sudo journalctl --vacuum-time=30d

Shrink the journal to a maximum size:

sudo journalctl --vacuum-size=500M

For permanent size and retention limits, configure /etc/systemd/journald.conf as described in our persistent journal storage guide.

Quick Reference

All the filtering commands in one table:

CommandWhat It Shows
journalctl -n 20Last 20 entries
journalctl -rReverse order (newest first)
journalctl -fFollow in real time
journalctl -u ssh.serviceEntries for a service
journalctl -p errErrors and above
journalctl -kKernel messages
journalctl -bCurrent boot only
journalctl -b -1Previous boot
journalctl --since "1 hour ago"Last hour
journalctl --since todayToday only
journalctl _PID=1234Specific process
journalctl _UID=0All root activity
journalctl -g "pattern"Grep messages
journalctl -o json-prettyJSON output
journalctl -o short-isoISO timestamps
journalctl -o verboseAll metadata fields
journalctl --disk-usageJournal disk usage
journalctl --vacuum-time=30dDelete entries older than 30 days

For managing scheduled tasks with systemd timers or controlling services with systemctl, check our other systemd guides.

Related Articles

Debian How To Configure NFS Server on  Debian 12 (Bookworm) Cloud What Is Azure Cost Optimization? Debian How To Install PHP with Apache on Ubuntu and Debian CentOS Solve Error: Package: docker-ce-xxx (docker-ce-stable) Requires: container-selinux >=

Leave a Comment

Press ESC to close