
How to Use journalctl to View and Manage systemd Logs
systemd’s journalctl is a powerful command-line utility that lets you query and view logs from the systemd journal, a centralized logging system that captures everything from kernel messages to application logs. Unlike traditional text-based log files scattered across /var/log, the systemd journal stores structured log data in a binary format, offering efficient querying, filtering, and correlation capabilities. This post will walk you through the essential journalctl commands, advanced filtering techniques, and practical troubleshooting scenarios that’ll make you more effective at diagnosing system issues and monitoring your Linux servers.
How systemd Journal Works
The systemd journal operates differently from traditional syslog systems. Instead of writing plain text files, it stores log entries in a structured binary format within /var/log/journal (persistent) or /run/log/journal (volatile). Each log entry contains metadata like timestamps, service names, process IDs, and priority levels, making filtering and searching significantly more efficient.
The journal daemon (systemd-journald) collects logs from multiple sources:
- Kernel log messages (similar to dmesg)
- System and service messages from systemd units
- Standard output and error streams from services
- Syslog messages from applications
- Audit records from the kernel audit subsystem
Here’s how the journal storage differs from traditional logging:
Aspect | systemd Journal | Traditional Syslog |
---|---|---|
Storage Format | Structured binary | Plain text files |
Query Performance | Indexed, fast filtering | Linear text search |
Metadata | Rich structured fields | Limited parsing required |
Rotation | Automatic size/time-based | Manual logrotate configuration |
Corruption Recovery | Built-in verification | Manual file recovery |
Essential journalctl Commands
Let’s start with the most commonly used journalctl commands that you’ll need for daily system administration:
# View all logs (equivalent to 'tail -f /var/log/messages' but better)
journalctl
# Follow logs in real-time (like tail -f)
journalctl -f
# Show logs for a specific service
journalctl -u nginx.service
# Show logs for the current boot only
journalctl -b
# Show logs from previous boot
journalctl -b -1
# Display logs with timestamps in UTC
journalctl --utc
# Show only kernel messages (like dmesg)
journalctl -k
# Reverse chronological order (newest first)
journalctl -r
# Show logs since a specific time
journalctl --since "2024-01-15 10:00:00"
journalctl --since yesterday
journalctl --since "1 hour ago"
# Show logs until a specific time
journalctl --until "2024-01-15 15:00:00"
# Combine time filters
journalctl --since "2024-01-15 10:00:00" --until "2024-01-15 15:00:00"
Advanced Filtering and Search Techniques
The real power of journalctl comes from its filtering capabilities. You can combine multiple filters to pinpoint exactly what you’re looking for:
# Filter by priority level (0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug)
journalctl -p err
journalctl -p warning..err # Range from warning to error
# Filter by specific process ID
journalctl _PID=1234
# Filter by user ID
journalctl _UID=1000
# Filter by executable path
journalctl _EXE=/usr/bin/python3
# Filter by systemd unit
journalctl _SYSTEMD_UNIT=apache2.service
# Filter by hostname (useful for centralized logging)
journalctl _HOSTNAME=webserver01
# Search for specific text patterns
journalctl -g "failed" # Grep-like search
journalctl -g "error|failed|exception" # Regex patterns
# Combine multiple filters (AND operation)
journalctl -u nginx.service -p err --since yesterday
# Show available fields for filtering
journalctl -N
For complex filtering scenarios, you can use field matching syntax:
# Multiple unit files
journalctl -u nginx.service -u apache2.service
# Specific syslog facility
journalctl SYSLOG_FACILITY=10
# Container-specific logs (useful for Docker/Podman)
journalctl CONTAINER_NAME=myapp
# Show logs from specific systemd slice
journalctl _SYSTEMD_SLICE=user-1000.slice
Output Formatting and Export Options
journalctl offers various output formats depending on your needs:
# JSON output (great for log analysis tools)
journalctl -u nginx.service -o json
# JSON pretty-printed
journalctl -u nginx.service -o json-pretty
# Short format (default)
journalctl -o short
# Verbose format (shows all available fields)
journalctl -o verbose
# Export format (suitable for backup/transfer)
journalctl -o export
# Cat format (just the message, no metadata)
journalctl -o cat
# Show only today's logs in JSON format
journalctl --since today -o json-pretty > today_logs.json
Performance tip: When processing large amounts of log data, use the export format with compression:
# Efficient log export for analysis
journalctl --since "2024-01-01" --until "2024-01-31" -o export | gzip > january_logs.gz
Real-World Troubleshooting Scenarios
Here are practical examples of using journalctl for common troubleshooting situations:
Debugging Service Startup Issues
# Check why a service failed to start
journalctl -u docker.service --since "10 minutes ago"
# Show detailed information about service state changes
journalctl -u postgresql.service -o verbose
# Find all services that failed during last boot
journalctl -b -p err _SYSTEMD_UNIT=*.service
Investigating System Performance Problems
# Monitor disk I/O related errors
journalctl -k -g "I/O error|blocked for more than"
# Check for memory pressure issues
journalctl -k -g "Out of memory|oom-killer|Memory cgroup"
# Network connectivity issues
journalctl -g "network unreachable|connection refused|timeout"
# Find processes causing high load
journalctl --since "1 hour ago" -g "load average"
Security and Authentication Monitoring
# SSH login attempts
journalctl -u ssh.service -g "Accepted|Failed"
# Sudo usage tracking
journalctl -g "sudo.*COMMAND"
# Failed authentication attempts
journalctl -p err -g "authentication failure|invalid user"
# SELinux/AppArmor denials
journalctl -g "denied|audit.*avc"
Journal Management and Maintenance
Managing journal disk usage is crucial for long-term system health:
# Check journal disk usage
journalctl --disk-usage
# Show journal file information
journalctl --list-boots
# Verify journal file integrity
journalctl --verify
# Clean up old journal entries
journalctl --vacuum-time=30d # Keep only 30 days
journalctl --vacuum-size=1G # Limit to 1GB total
journalctl --vacuum-files=10 # Keep only 10 journal files
# Rotate journal files
journalctl --rotate
Configuration options in /etc/systemd/journald.conf:
# Example journald.conf settings
[Journal]
# Persistent storage (survives reboots)
Storage=persistent
# Maximum disk usage
SystemMaxUse=2G
SystemKeepFree=500M
# Maximum file size
SystemMaxFileSize=128M
# How long to keep entries
MaxRetentionSec=3month
# Forward to syslog (if needed for legacy tools)
ForwardToSyslog=yes
# Compression
Compress=yes
Integration with Monitoring and Analysis Tools
journalctl works well with various log analysis tools:
Exporting to ELK Stack
# Export logs in JSON format for Elasticsearch
journalctl --since yesterday -o json | while read line; do
echo "$line" | curl -X POST "localhost:9200/systemd-logs/_doc" \
-H "Content-Type: application/json" -d @-
done
Integration with Prometheus/Grafana
Use tools like node_exporter with custom text file collectors:
# Count error logs for metrics
#!/bin/bash
ERROR_COUNT=$(journalctl --since "5 minutes ago" -p err --no-pager -q | wc -l)
echo "systemd_errors_total $ERROR_COUNT" > /var/lib/node_exporter/systemd_errors.prom
Best Practices and Common Pitfalls
- Resource Management: Monitor journal disk usage regularly. Uncontrolled growth can fill up your root filesystem.
- Time Synchronization: Ensure accurate system time with NTP/chrony for meaningful log correlation across multiple systems.
- Structured Logging: When writing applications, use structured logging formats that journal can parse effectively.
- Backup Strategy: Include journal files in your backup strategy, especially for compliance requirements.
- Performance: For high-throughput logging, consider adjusting RateLimitIntervalSec and RateLimitBurst in journald.conf.
Common pitfalls to avoid:
- Don’t parse journal output with shell tools: Use journalctl’s built-in filtering instead of piping to grep/awk when possible.
- Avoid overly broad time ranges: Querying months of logs can be slow; use specific time windows.
- Check permissions: Regular users can only see their own logs unless they’re in the systemd-journal group.
Comparison with Alternative Logging Solutions
Feature | systemd Journal | rsyslog | syslog-ng | Fluentd |
---|---|---|---|---|
Setup Complexity | Built-in, minimal config | Moderate configuration | Complex configuration | Requires separate installation |
Query Performance | Fast, indexed | Slow (text search) | Moderate | Depends on backend |
Remote Logging | Limited (systemd-journal-remote) | Excellent | Excellent | Excellent |
Log Processing | Basic filtering | Advanced processing | Very advanced | Plugin ecosystem |
Resource Usage | Low | Low | Moderate | Moderate to high |
For centralized logging in enterprise environments, you might want to forward journal logs to dedicated log management systems:
# Forward journal to remote syslog server
# /etc/systemd/journald.conf
[Journal]
ForwardToSyslog=yes
# Then configure rsyslog to forward
# /etc/rsyslog.conf
*.* @@logserver.example.com:514
The systemd journal excels at local log management and debugging, while traditional syslog solutions are better for complex log processing and centralized collection. Many administrators use both systems together, leveraging journal’s superior local querying capabilities while forwarding critical logs to centralized systems for long-term storage and analysis.
For additional information, check out the official journalctl manual page and systemd-journald documentation for comprehensive configuration options and advanced use cases.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.