Read systemd Logs With journalctl
journalctl is the primary utility for querying and displaying logs collected by systemd-journald , the logging service within the systemd ecosystem.…
journalctl is the primary utility for querying and displaying logs collected by systemd-journald, the logging service within the systemd ecosystem. Unlike traditional syslog, systemd-journald stores logs in a structured, binary format, offering enhanced querying capabilities, reliable timestamps, and metadata preservation. This article delves into the practical aspects of using journalctl to efficiently navigate, filter, and export system logs on Linux systems utilizing systemd.
Understanding systemd-journald Persistence
By default, systemd-journald logs are often stored in volatile memory (/run/log/journal) and are thus lost across reboots. For most production environments, persistent logging is critical. To enable persistence, you must create a directory for the journal files on disk:
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald.service
After this, systemd-journald will store its journal files under /var/log/journal/<machine-id>/. The <machine-id> is a unique identifier for the system, ensuring logs are properly segregated if the /var/log/journal directory is shared (e.g., in a container environment or shared storage setup, though this is uncommon for journald). You can verify the storage location with:
journalctl --disk-usage
This command will show the total disk space consumed by the journal files and their storage path. For finer control over journal persistence, such as limiting disk usage or enabling compression, edit /etc/systemd/journald.conf. Relevant parameters include:
Storage=persistent: Ensures logs are saved to/var/log/journal. Other options areauto(default, persistent if/var/log/journalexists),volatile, andnone.SystemMaxUse=500M: Sets a maximum disk usage for the journal, e.g., 500 MB.SystemKeepFree=10%: Ensures that at least 10% of the disk space remains free.Compress=yes: Compresses older journal files to save disk space.
After modifying journald.conf, restart the service for changes to take effect: sudo systemctl restart systemd-journald.service.
Basic Log Inspection and Following
The simplest way to view all collected logs is journalctl without any arguments. This displays all logs from the oldest entry to the newest, paginated by default using a pager like less.
journalctl
To view logs in real-time, similar to tail -f, use the -f or --follow flag:
journalctl -f
This is particularly useful for monitoring system activity or application output as it happens.
Filtering by systemd Unit
One of the most powerful features of journalctl is its ability to filter logs by specific systemd units. This is invaluable for debugging service-related issues.
journalctl -u nginx.service
journalctl -u sshd.service -f
The first command shows all logs for the nginx service. The second command follows logs for the sshd service in real-time. You can omit the .service suffix for most common unit types (e.g., nginx instead of nginx.service).
To view logs for multiple units, simply specify them:
journalctl -u nginx -u php-fpm
Filtering by Time
journalctl offers flexible time-based filtering. The --since and --until flags accept various formats:
- Relative times:
"1 hour ago","20 minutes ago","yesterday","now" - Absolute times:
"2023-10-27 10:30:00","2023-10-27 10:30" - Specific dates:
"2023-10-27"
# Show logs from the last hour
journalctl --since "1 hour ago"
# Show logs from yesterday until 5 minutes ago
journalctl --since "yesterday" --until "5 minutes ago"
# Show logs for a specific time window for the SSH daemon
journalctl -u sshd --since "2023-10-27 08:00" --until "2023-10-27 09:00"
Output Formatting
By default, journalctl outputs human-readable text. However, for scripting or integration with other tools, different output formats are available via the -o or --output flag:
| Format | Description | Example Use Case |
|---|---|---|
short |
Default syslog-like format (e.g., Oct 27 10:30:05 hostname sshd[1234]: ...) |
Quick terminal inspection |
short-iso |
ISO 8601 timestamps | Standardized time display |
verbose |
Full structured log entries with all fields | Detailed debugging, understanding all available metadata |
json |
One JSON object per log entry | Machine parsing, integration with JSON-aware tools |
json-pretty |
Pretty-printed JSON | Easier-to-read JSON for humans |
export |
Binary journal format | Transferring logs between systems with journalctl --file= |
# View logs in JSON format for the Nginx service
journalctl -u nginx -o json
# View verbose logs for the last 10 lines
journalctl -n 10 -o verbose
The -n or --lines flag specifies the number of lines to display, similar to tail -n.
Advanced Filtering
Beyond basic unit and time filtering, journalctl supports more granular selection criteria.
Filtering by Priority/Severity
Logs have different priority levels (e.g., error, warning, info, debug). Use the -p or --priority flag:
# Show all error (priority 3) and critical (priority 2) messages
journalctl -p err
# Show logs with priority level warning (4) or higher (lower number = higher priority)
journalctl -p warning
# Priority levels:
# 0: emerg (system is unusable)
# 1: alert (action must be taken immediately)
# 2: crit (critical conditions)
# 3: err (error conditions)
# 4: warning (warning conditions)
# 5: notice (normal but significant condition)
# 6: info (informational messages)
# 7: debug (debug-level messages)
Filtering by Fields
systemd-journald collects numerous structured fields with each log entry. You can filter by these fields directly. Common fields include:
_PID: Process ID_UID: User ID_COMM: Executable name_SYSTEMD_UNIT: systemd unit name (same as-ufilter)_HOSTNAME: Hostname of the logging machineMESSAGE: The actual log message content
# Show messages from a specific PID
journalctl _PID=1234
# Show logs from the 'bash' executable
journalctl _COMM=bash
# Show kernel logs (boot messages)
journalctl -k
# Show messages related to network interfaces
journalctl -g "eth0|enp" # -g is for grep-like matching on MESSAGE field
For a complete list of fields available in an entry, use journalctl -o verbose.
Exporting Logs to Syslog or Files
While journalctl is powerful, some centralized logging systems (SIEMs) or legacy tools might still expect classic syslog format. systemd-journald can forward logs to a traditional syslog daemon (e.g., rsyslog or syslog-ng) if one is running. This is usually configured by default on most distributions, where rsyslog is set up to read from /run/systemd/journal/syslog.
To manually export logs, you can pipe journalctl output:
# Export all logs for Nginx to a file in default short format
journalctl -u nginx > nginx_logs.txt
# Export all logs from today in JSON format to a compressed file
journalctl --since "today" -o json | gzip > today_logs.json.gz
# Export binary journal data for later analysis on another system
journalctl -u httpd --since "1 week ago" -o export > httpd_journal_export.journal
To analyze an exported binary journal file on another machine:
journalctl --file=httpd_journal_export.journal
Common Pitfalls and Troubleshooting
- Volatile Logs Lost on Reboot: If your logs disappear after a reboot,
systemd-journaldis likely configured for volatile storage. Create/var/log/journaland restartsystemd-journald.serviceas described above. - Disk Space Consumption: Persistent journals can consume significant disk space. Regularly monitor
journalctl --disk-usageand configureSystemMaxUseandSystemKeepFreein/etc/systemd/journald.confto manage this. - Time Zone Issues:
journalctlby default displays timestamps in the local system's timezone. This can be confusing when analyzing logs from systems in different timezones. Use-uor--utcto display timestamps in UTC. - Missing Application Logs: If an application's logs are not appearing in
journalctl, ensure it's properly configured to send output tostdoutorstderr, especially if it's run as asystemdservice.systemdcaptures these streams automatically. If the application writes to its own log files,journalctlwill not see them unless a mechanism likesystemd-journal-remoteor a log forwarder is used. - Permissions: Regular users can typically read journal logs. If a user cannot access logs, check permissions on
/var/log/journal. Groupsystemd-journaloften has read access. Adding a user to this group (sudo usermod -aG systemd-journal <username>) might be necessary, followed by re-logging for changes to take effect.