Chapter 12 ⏱️ 50 min read 📚 Intermediate

Analyze System Logs

Master system logging with journalctl and rsyslog. Learn to query systemd journal, configure persistent logging, analyze boot logs, and manage traditional syslog files.

🎯 Introduction to Logging

RHEL 9 uses two logging systems: systemd-journald (binary journal) and rsyslog (text files). Both work together to provide comprehensive system logging.

Logging Systems

System Format Location Tool
systemd-journald Binary /run/log/journal (volatile) journalctl
rsyslog Text /var/log/* less, grep, tail

Common Log Files (rsyslog)

File Contents
/var/log/messages General system messages
/var/log/secure Authentication/authorization logs
/var/log/audit/audit.log SELinux audit events
/var/log/cron Cron job execution
/var/log/boot.log System boot messages
/var/log/maillog Mail server logs

Log Priority Levels

# From highest to lowest priority:
0 emerg    # System unusable
1 alert    # Immediate action required
2 crit     # Critical conditions
3 err      # Error conditions
4 warning  # Warning conditions
5 notice   # Normal but significant
6 info     # Informational messages
7 debug    # Debug messages

📜 journalctl - systemd Journal

Basic journalctl Commands

# View all journal entries (oldest first)
journalctl

# View in reverse (newest first)
journalctl -r

# Follow live logs (like tail -f)
journalctl -f

# Show only kernel messages
journalctl -k
# or
journalctl --dmesg

# Show N most recent entries
journalctl -n 50

# No paging (output all at once)
journalctl --no-pager

Filtering by Time

# Show logs since last boot
journalctl -b

# Show logs from previous boot
journalctl -b -1

# List all boots
journalctl --list-boots

# Since specific time
journalctl --since "2025-01-13 10:00:00"
journalctl --since "1 hour ago"
journalctl --since yesterday
journalctl --since today

# Until specific time
journalctl --until "2025-01-13 12:00:00"

# Between times
journalctl --since "2025-01-13 09:00" --until "2025-01-13 17:00"

Filtering by Service/Unit

# Show logs for specific service
journalctl -u sshd
journalctl -u httpd.service

# Multiple units
journalctl -u sshd -u httpd

# Since last boot for service
journalctl -u sshd -b

# Follow service logs
journalctl -u httpd -f

Filtering by Priority

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

# Show warnings and above
journalctl -p warning

# Show specific priority
journalctl -p 3  # err level

# Priority range
journalctl -p err -p warning

Filtering by Process/User

# Filter by PID
journalctl _PID=1234

# Filter by user ID
journalctl _UID=1000

# Filter by executable
journalctl _COMM=sshd

# Filter by systemd unit
journalctl _SYSTEMD_UNIT=httpd.service

Output Formats

# Detailed output (default)
journalctl -o verbose

# Short format (syslog style)
journalctl -o short

# JSON format
journalctl -o json

# JSON pretty-print
journalctl -o json-pretty

# Export format (for backup)
journalctl -o export

# Show messages only
journalctl -o cat

Combining Filters

# Service logs since last boot, errors only
journalctl -u sshd -b -p err

# Recent httpd errors
journalctl -u httpd -p err -n 20

# Today's authentication logs
journalctl -u sshd --since today -o short-precise

Disk Usage

# Show journal disk usage
journalctl --disk-usage

# Output example:
Archived and active journals take up 512.0M in the file system.

# Verify journal files
journalctl --verify

Procedure: Troubleshooting Service Failure

  1. Check service status:
    systemctl status httpd
  2. View service logs:
    journalctl -u httpd -n 50
  3. Check for errors since last boot:
    journalctl -u httpd -b -p err
  4. Follow logs while restarting:
    # Terminal 1:
    journalctl -u httpd -f
    
    # Terminal 2:
    sudo systemctl restart httpd
  5. Check timestamps for specific error:
    journalctl -u httpd --since "5 minutes ago" -o short-precise

💾 Persistent Journal Storage

By default, systemd journal is stored in /run/log/journal (lost on reboot). Enable persistent storage to keep logs across reboots.

Enable Persistent Journal

# Create directory for persistent journal
sudo mkdir -p /var/log/journal

# Set ownership and permissions
sudo chown root:systemd-journal /var/log/journal
sudo chmod 2755 /var/log/journal

# Restart journald to use new location
sudo systemctl restart systemd-journald

# Or configure in /etc/systemd/journald.conf:
sudo vi /etc/systemd/journald.conf

[Journal]
Storage=persistent
SystemMaxUse=500M
SystemKeepFree=1G
MaxRetentionSec=1month

# Restart journald
sudo systemctl restart systemd-journald

Journal Configuration

Setting Description
Storage=persistent Store in /var/log/journal
Storage=volatile Store in /run/log/journal (default)
SystemMaxUse= Max disk space for journal
MaxRetentionSec= Max age of journal entries

Managing Journal Size

# Manually rotate journal
sudo journalctl --rotate

# Vacuum by size (keep only 500M)
sudo journalctl --vacuum-size=500M

# Vacuum by time (keep only 2 weeks)
sudo journalctl --vacuum-time=2weeks

# Vacuum by file count
sudo journalctl --vacuum-files=5

# Check space after vacuum
journalctl --disk-usage
📘 Journal Location

/run/log/journal: Volatile (RAM-based, lost on reboot)
/var/log/journal: Persistent (disk-based, survives reboot)
If /var/log/journal exists, it's used automatically.

📋 rsyslog - Traditional Logging

rsyslog receives logs from journald and writes them to text files in /var/log/.

rsyslog Configuration

# Main config file
/etc/rsyslog.conf

# Additional configs
/etc/rsyslog.d/*.conf

# Example configuration format:
facility.priority    action

# Examples:
*.info;mail.none;authpriv.none;cron.none    /var/log/messages
authpriv.*                                   /var/log/secure
mail.*                                       /var/log/maillog
cron.*                                       /var/log/cron

Facilities and Priorities

# Facilities:
auth, authpriv  # Security/authentication
cron            # Cron daemon
daemon          # System daemons
kern            # Kernel messages
mail            # Mail system
user            # User-level messages
local0-local7   # Custom applications

# Priority selectors:
*          # All priorities
none       # No priorities
.priority  # This priority and above
.=priority # Exactly this priority
.!priority # Not this priority

Viewing Traditional Logs

# View messages log
sudo less /var/log/messages
sudo tail -f /var/log/messages

# View authentication logs
sudo tail -f /var/log/secure

# Search for pattern
sudo grep "Failed password" /var/log/secure

# Last 20 lines
sudo tail -20 /var/log/messages

# Follow multiple logs
sudo tail -f /var/log/messages /var/log/secure

Custom rsyslog Rule

# Create custom log for httpd
sudo vi /etc/rsyslog.d/httpd.conf

# Add:
if $programname == 'httpd' then /var/log/httpd-custom.log
& stop

# Restart rsyslog
sudo systemctl restart rsyslog

# Verify
logger -t httpd "Test message"
sudo tail /var/log/httpd-custom.log

Remote Logging

# Configure client to send logs to remote server
sudo vi /etc/rsyslog.conf

# Add (UDP):
*.* @192.168.1.100:514

# Or (TCP):
*.* @@192.168.1.100:514

# Restart
sudo systemctl restart rsyslog

🔄 Log Rotation

logrotate manages log file rotation to prevent filling disk space.

logrotate Configuration

# Main config
/etc/logrotate.conf

# Service-specific configs
/etc/logrotate.d/

# Example config for custom log
sudo vi /etc/logrotate.d/myapp

/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0640 root root
    sharedscripts
    postrotate
        systemctl reload myapp > /dev/null 2>&1 || true
    endscript
}

logrotate Directives

Directive Description
daily/weekly/monthly Rotation frequency
rotate N Keep N rotated logs
compress Compress rotated logs with gzip
delaycompress Compress on next rotation
missingok Don't error if log missing
notifempty Don't rotate if empty
create MODE OWNER GROUP Create new log file

Manual Rotation

# Test rotation (dry run)
sudo logrotate -d /etc/logrotate.d/myapp

# Force rotation
sudo logrotate -f /etc/logrotate.d/myapp

# Rotate all logs
sudo logrotate /etc/logrotate.conf

# Check rotation status
cat /var/lib/logrotate/logrotate.status

📝 Practice Questions

Question 1: What command shows logs since the last boot?

  • A) journalctl --boot
  • B) journalctl -b
  • C) Both A and B
  • D) journalctl --since boot
Answer: C) Both A and B
journalctl -b and journalctl --boot are equivalent. Use -b -1 for previous boot, -b -2 for two boots ago. --list-boots shows all available boots.

Question 2: How do you enable persistent journal storage?

  • A) Create /var/log/journal directory
  • B) Set Storage=persistent in journald.conf
  • C) Both A and B
  • D) Edit /etc/fstab
Answer: C) Both A and B
Either method works: create /var/log/journal (automatic) or set Storage=persistent in /etc/systemd/journald.conf. Directory method is simpler. Don't forget to restart systemd-journald after changes.

Question 3: Which log file contains authentication failures?

  • A) /var/log/messages
  • B) /var/log/secure
  • C) /var/log/auth.log
  • D) /var/log/faillog
Answer: B) /var/log/secure
/var/log/secure contains authentication and authorization logs (SSH logins, sudo usage, etc.). Use grep "Failed password" /var/log/secure to find failed login attempts. Or use journalctl: journalctl -u sshd

Question 4: What command follows live journal logs like "tail -f"?

  • A) journalctl -f
  • B) journalctl --follow
  • C) Both A and B
  • D) journalctl -tail
Answer: C) Both A and B
journalctl -f and journalctl --follow both work. Combine with -u for specific service: journalctl -u httpd -f. Press Ctrl+C to stop following.

Question 5: How do you limit journal to 500MB?

  • A) journalctl --vacuum-size=500M
  • B) Set SystemMaxUse=500M in journald.conf
  • C) Both A and B
  • D) logrotate -s 500M
Answer: C) Both A and B
--vacuum-size immediately cleans up. SystemMaxUse in /etc/systemd/journald.conf sets permanent limit. Can also use --vacuum-time=2weeks to delete old entries. Check current size: journalctl --disk-usage

Question 6: What priority shows only errors and worse?

  • A) journalctl -p warning
  • B) journalctl -p err
  • C) journalctl -p crit
  • D) journalctl -p 3
Answer: B or D (both correct)
-p err shows errors and above (emerg, alert, crit, err). Priority 3 = err. -p warning includes warnings (less strict). -p crit only critical and above (more strict). Priorities: 0=emerg, 1=alert, 2=crit, 3=err, 4=warning, 5=notice, 6=info, 7=debug.