How to Use journalctl for Systemd Log Analysis on RHEL 7
On RHEL 7, the traditional syslog infrastructure is complemented — and in many cases replaced — by the systemd journal, managed by systemd-journald. The journalctl command is your primary interface for querying, filtering, and exporting log data collected by this service. Unlike flat text log files, the journal stores structured binary data that can be searched across dozens of metadata fields including unit name, priority, process ID, and boot session. This guide walks you through the most important journalctl techniques every RHEL 7 administrator should know.
Prerequisites
- A running RHEL 7 system with
systemd(default since RHEL 7.0) - Root or
sudoaccess for reading all journal entries - Basic familiarity with the command line and systemd unit names
Step 1: Understanding the Journal and Basic Usage
The systemd journal is collected by the systemd-journald daemon. By default on a fresh RHEL 7 installation, journal data is stored only in memory at /run/log/journal/ and does not persist across reboots. Running journalctl without arguments displays the entire journal, oldest entries first, piped through a pager:
journalctl
Use arrow keys or Page Up/Down to scroll. Press q to quit. To see the most recent entries first, use the reverse flag:
journalctl -r
To limit the output to the last N lines (similar to tail), use -n:
# Show the last 50 journal entries
journalctl -n 50
# Show the last 100 entries (default when -n is given alone)
journalctl -n
Step 2: Following the Journal in Real Time
The -f flag streams new journal entries to your terminal as they arrive, similar to tail -f on a log file. This is extremely useful when troubleshooting a service that is actively failing or starting up:
# Stream all new journal entries
journalctl -f
# Stream only entries from a specific unit
journalctl -f -u sshd
Press Ctrl+C to stop the stream.
Step 3: Filtering by Systemd Unit with -u
The -u flag filters journal output to entries produced by a specific systemd unit. This is one of the most frequently used filtering options:
# View all logs for the SSH daemon
journalctl -u sshd
# View logs for the Apache HTTP server
journalctl -u httpd
# Combine -u with -n to limit output
journalctl -u crond -n 30
# View logs for multiple units at once
journalctl -u httpd -u mysqld
Unit names are case-sensitive and must match the .service unit name exactly. You can find the correct name with systemctl list-units.
Step 4: Filtering by Time with –since and –until
The --since and --until options let you narrow log output to a specific time window. They accept natural language date/time strings:
# Entries from the past hour
journalctl --since "1 hour ago"
# Entries since a specific date and time
journalctl --since "2024-03-15 08:00:00"
# Entries between two timestamps
journalctl --since "2024-03-15 08:00:00" --until "2024-03-15 09:00:00"
# Entries from today
journalctl --since today
# Combine with unit filter
journalctl -u httpd --since "2024-03-15" --until "2024-03-16"
Step 5: Filtering by Priority with -p
The -p option filters by syslog priority level. Specifying a level shows entries at that level and all higher-severity levels. Priority levels (from most to least severe) are:
0— emerg1— alert2— crit3— err4— warning5— notice6— info7— debug
# Show only errors and above (emerg, alert, crit, err)
journalctl -p err
# Show warnings and above
journalctl -p warning
# Show only critical messages for a specific service
journalctl -u kernel -p crit
Step 6: Viewing Logs from a Specific Boot with -b
The -b flag filters journal entries to a specific boot session. Without an argument, it shows the current boot:
# Current boot entries only
journalctl -b
# Previous boot (requires persistent journal)
journalctl -b -1
# Two boots ago
journalctl -b -2
# List all recorded boots
journalctl --list-boots
Note that boot offsets beyond -b -1 require a persistent journal (see Step 7).
Step 7: Enabling Persistent Journal Storage
By default, RHEL 7 may store the journal only in RAM (/run/log/journal/), which is lost on reboot. To enable persistence, edit the journal configuration file:
vi /etc/systemd/journald.conf
Find and set the Storage directive:
[Journal]
Storage=persistent
Then create the persistent storage directory and restart the service:
mkdir -p /var/log/journal
systemctl restart systemd-journald
Journal data will now be written to /var/log/journal/ and will survive reboots.
Step 8: Controlling Journal Size Limits
Left unchecked, a persistent journal can consume significant disk space. Configure size limits in /etc/systemd/journald.conf:
[Journal]
Storage=persistent
# Maximum disk space the journal may use
SystemMaxUse=500M
# Maximum size of individual journal files
SystemMaxFileSize=50M
# Keep at least this much free on the filesystem
SystemKeepFree=1G
# Maximum time to retain journal entries
MaxRetentionSec=1month
After editing, restart systemd-journald:
systemctl restart systemd-journald
To manually vacuum old journal data to stay within a size or time limit:
# Remove journal data older than 2 weeks
journalctl --vacuum-time=2weeks
# Reduce journal to no more than 200MB
journalctl --vacuum-size=200M
Step 9: Exporting Journal Logs
The journal can be exported in several formats for archival, shipping to a SIEM, or analysis with other tools:
# Export as plain text (no pager)
journalctl --no-pager > /tmp/journal_export.txt
# Export in JSON format (one JSON object per line)
journalctl -u sshd -o json > /tmp/sshd_journal.json
# Export in JSON with pretty-printing
journalctl -u sshd -o json-pretty > /tmp/sshd_journal_pretty.json
# Export in native binary format (for transfer to another system)
journalctl -o export > /tmp/journal.export
# Export entries from a time range
journalctl --since "2024-03-15" --until "2024-03-16" --no-pager > /tmp/march15.txt
Available output formats include short (default), short-iso, json, json-pretty, cat, export, and verbose.
Step 10: Useful Advanced Filtering
The journal supports filtering on any structured field. Some useful examples:
# Filter by process ID
journalctl _PID=1234
# Filter by executable path
journalctl _EXE=/usr/sbin/sshd
# Filter by username (UID)
journalctl _UID=1000
# Show kernel messages only (equivalent to dmesg)
journalctl -k
# Show messages from this boot with errors, no pager
journalctl -b -p err --no-pager
You can check the current disk usage of the journal at any time with:
journalctl --disk-usage
Conclusion
journalctl is an indispensable tool for RHEL 7 system administrators. Its ability to filter by unit, time range, boot session, priority level, and arbitrary structured fields makes it far more powerful than traditional grep-based log analysis. By enabling persistent storage and setting sensible size limits in /etc/systemd/journald.conf, you ensure that historical log data is available for forensic analysis and compliance auditing. Combine journalctl with systemctl status for a complete picture of service health on your RHEL 7 systems.