cobol
prometheus
+
+
travis
influxdb
+
https
+
circle
deno
+
+
riot
+
+
+
+
sublime
+
+
+
+
+
vite
influxdb
node
docker
+
+
+
solidity
{}
+
+
+
+
+
+
js
+
mvn
+
elasticsearch
+
rs
+
+
+
>=
websocket
+
+
redis
vite
+
phpstorm
ember
tcl
pandas
+
goland
+
+
+
+
koa
+
+
+
+
+
+
+
ocaml
+
+
+
+
π
+
+
istio
+
gulp
+
+
+
Back to Blog
Managing System Logs with journalctl in AlmaLinux
AlmaLinux journalctl System Logs

Managing System Logs with journalctl in AlmaLinux

Published Jul 19, 2025

Master systemd journal management in AlmaLinux using journalctl. Learn advanced log filtering, analysis techniques, persistence configuration, and troubleshooting strategies for effective system monitoring

19 min read
0 views
Table of Contents

Introduction

The systemd journal, managed through journalctl, has revolutionized log management in modern Linux distributions like AlmaLinux. Unlike traditional text-based log files, the systemd journal provides a structured, indexed, and centralized logging system that captures everything from kernel messages to application logs. This comprehensive guide explores journalctl’s powerful features, from basic queries to advanced filtering and analysis techniques.

Understanding the systemd Journal

Architecture Overview

The systemd journal collects and stores log data in a structured format:

  • Binary Storage: Logs stored in binary format for efficiency
  • Structured Data: Metadata-rich entries with indexed fields
  • Centralized Collection: All system logs in one place
  • Automatic Rotation: Built-in log rotation and size management
  • Cryptographic Sealing: Optional log authentication

Journal Components

# View journal configuration
cat /etc/systemd/journald.conf

# Check journal service status
systemctl status systemd-journald

# View journal disk usage
journalctl --disk-usage

# Verify journal integrity
journalctl --verify

Basic journalctl Usage

Viewing Logs

# View all logs (oldest first)
journalctl

# View logs in reverse order (newest first)
journalctl -r

# Follow log output in real-time
journalctl -f

# Show most recent entries
journalctl -n 50

# View logs from current boot
journalctl -b

# View logs from previous boot
journalctl -b -1

# List all boots
journalctl --list-boots

Output Formatting

# Different output formats
journalctl -o short          # Default syslog style
journalctl -o short-iso      # ISO 8601 timestamps
journalctl -o short-precise  # Microsecond precision
journalctl -o short-monotonic # Monotonic timestamps
journalctl -o verbose        # Full structured data
journalctl -o export         # Export format
journalctl -o json           # JSON format
journalctl -o json-pretty    # Pretty-printed JSON
journalctl -o cat            # Message only

# Disable pager
journalctl --no-pager

# Output to file
journalctl > system_logs.txt

# Export in binary format
journalctl -o export > journal_export.log

Time-Based Filtering

Date and Time Filters

# Logs since specific date
journalctl --since "2024-07-19"

# Logs until specific date
journalctl --until "2024-07-20"

# Logs within date range
journalctl --since "2024-07-19" --until "2024-07-20"

# Logs from last hour
journalctl --since "1 hour ago"

# Various time formats
journalctl --since "2024-07-19 10:00:00"
journalctl --since "10:00" --until "11:00"
journalctl --since yesterday
journalctl --since today
journalctl --since "5 minutes ago"
journalctl --since "2 days ago" --until "1 day ago"

# Combining with other filters
journalctl --since "2024-07-19" -u sshd.service

Boot-Based Filtering

# Current boot logs
journalctl -b 0
journalctl -b

# Previous boot
journalctl -b -1

# Specific boot by ID
journalctl -b 5d4851c6b0f74c17962e4685826e0c49

# List boots with timestamps
journalctl --list-boots

# Logs from all boots
journalctl --boot=all

# Filter by boot and time
journalctl -b -1 --since "10:00" --until "11:00"

Unit and Service Filtering

Service-Specific Logs

# View logs for specific service
journalctl -u nginx.service
journalctl -u sshd

# Multiple services
journalctl -u nginx.service -u php-fpm.service

# Service logs with follows
journalctl -u httpd -f

# Service logs from current boot
journalctl -b -u NetworkManager

# Pattern matching for units
journalctl -u "systemd-*"

# View available units
systemctl list-units --type=service

System Component Logs

# Kernel messages
journalctl -k
journalctl --dmesg

# Logs from specific executable
journalctl /usr/sbin/sshd
journalctl /usr/bin/sudo

# Logs by systemd facility
journalctl -t kernel
journalctl -t systemd
journalctl -t audit

Priority and Severity Filtering

Log Priorities

# Filter by priority (and above)
journalctl -p err         # Error and above
journalctl -p warning     # Warning and above
journalctl -p notice      # Notice and above
journalctl -p info        # Info and above
journalctl -p debug       # All messages

# 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

# Specific priority only
journalctl -p warning..warning

# Priority range
journalctl -p err..warning

# Combine with service
journalctl -u httpd -p err

Examples by Severity

# Critical system errors
journalctl -p 0..3 --since today

# All warnings from specific service
journalctl -u mysql.service -p warning

# Debug messages for troubleshooting
journalctl -u NetworkManager -p debug --since "10 minutes ago"

# Emergency and alert messages only
journalctl -p 0..1

Advanced Filtering

Field-Based Filtering

# Filter by PID
journalctl _PID=1234

# Filter by UID
journalctl _UID=1000

# Filter by GID
journalctl _GID=100

# Filter by hostname
journalctl _HOSTNAME=server01

# Filter by command
journalctl _COMM=sshd

# Filter by executable path
journalctl _EXE=/usr/bin/ssh

# Filter by systemd unit
journalctl _SYSTEMD_UNIT=sshd.service

# Multiple field filters
journalctl _SYSTEMD_UNIT=httpd.service _PID=5678

# Filter by transport
journalctl _TRANSPORT=kernel
journalctl _TRANSPORT=syslog
journalctl _TRANSPORT=journal

Custom Field Queries

# Show available fields
journalctl --fields

# Show values for specific field
journalctl -F _SYSTEMD_UNIT
journalctl -F _COMM
journalctl -F PRIORITY

# Complex field matching
journalctl SYSLOG_FACILITY=4 # auth facility
journalctl SYSLOG_FACILITY=10 # authpriv facility

# Message content filtering
journalctl MESSAGE="*failed*"

# Custom application fields
journalctl MY_APP_FIELD=value

Using grep with journalctl

# Basic grep filtering
journalctl | grep -i error
journalctl | grep -i "failed password"

# Grep with context
journalctl | grep -A 5 -B 5 "kernel panic"

# Multiple patterns
journalctl | grep -E "(error|warning|critical)"

# Inverse matching
journalctl | grep -v debug

# Count occurrences
journalctl -u sshd | grep -c "Failed password"

User and Session Logs

User-Specific Logs

# Current user logs
journalctl --user

# Specific user logs (requires privileges)
journalctl _UID=1000

# User session logs
loginctl list-sessions
journalctl --user-unit=session-3.scope

# User service logs
journalctl --user -u myapp.service

# All user units
journalctl --user --all

Session and Login Tracking

# Login/logout events
journalctl -u systemd-logind

# SSH sessions
journalctl -u sshd | grep "session opened"

# Failed login attempts
journalctl _SYSTEMD_UNIT=sshd.service | grep "Failed"

# Authentication logs
journalctl -t sshd -t sudo -t su

# User switching events
journalctl _COMM=su
journalctl _COMM=sudo

Log Persistence and Rotation

Configuring Persistence

# Edit journal configuration
sudo vim /etc/systemd/journald.conf

# Key settings:
[Journal]
Storage=persistent        # Options: volatile, persistent, auto, none
Compress=yes             # Compress journal files
Seal=yes                 # Enable FSS sealing
SplitMode=uid           # Split by uid

# Size limits
SystemMaxUse=1G         # Maximum disk usage for system
SystemKeepFree=1G       # Keep free space
SystemMaxFileSize=100M  # Maximum individual file size
RuntimeMaxUse=100M      # Maximum runtime storage
RuntimeKeepFree=100M    # Runtime free space
RuntimeMaxFileSize=10M  # Runtime file size

# Time limits
MaxRetentionSec=1month  # Maximum retention time
MaxFileSec=1week        # Maximum file age

# Apply changes
sudo systemctl restart systemd-journald

Manual Maintenance

# Rotate journal files
sudo journalctl --rotate

# Vacuum by size
sudo journalctl --vacuum-size=500M

# Vacuum by time
sudo journalctl --vacuum-time=1month

# Vacuum by number of files
sudo journalctl --vacuum-files=10

# Verify and clean corrupted files
sudo journalctl --verify
sudo journalctl --sync

# Check disk usage
journalctl --disk-usage
du -sh /var/log/journal/

Real-Time Monitoring

Following Logs

# Follow all logs
journalctl -f

# Follow specific unit
journalctl -u nginx -f

# Follow with number of lines
journalctl -f -n 100

# Follow kernel messages
journalctl -k -f

# Follow with priority filter
journalctl -f -p err

# Follow multiple units
journalctl -f -u httpd -u php-fpm

# Follow with grep
journalctl -f | grep -i error

Monitoring Scripts

# Create monitoring script
cat > /usr/local/bin/monitor-errors.sh << 'EOF'
#!/bin/bash
# Monitor system errors in real-time

echo "Monitoring system errors..."
journalctl -f -p err --no-pager | while read line; do
    echo "[ERROR] $line"
    # Send alert (example)
    # echo "$line" | mail -s "System Error on $(hostname)" [email protected]
done
EOF

chmod +x /usr/local/bin/monitor-errors.sh

# Monitor specific patterns
cat > /usr/local/bin/monitor-failures.sh << 'EOF'
#!/bin/bash
# Monitor authentication failures

journalctl -f | grep -i "failed\|error\|denied" | while read line; do
    if echo "$line" | grep -q "authentication failure"; then
        echo "[AUTH FAILURE] $line"
        logger -p auth.warning "Authentication failure detected: $line"
    fi
done
EOF

chmod +x /usr/local/bin/monitor-failures.sh

Analyzing Logs

Statistical Analysis

# Count messages by priority
for p in {0..7}; do
    count=$(journalctl -p $p..$p --no-pager | wc -l)
    echo "Priority $p: $count messages"
done

# Top services by log volume
journalctl --no-pager | grep -oP '_SYSTEMD_UNIT=\K[^ ]+' | sort | uniq -c | sort -rn | head -20

# Errors per hour
for hour in {00..23}; do
    count=$(journalctl --since "today $hour:00" --until "today $hour:59" -p err --no-pager | wc -l)
    echo "Hour $hour: $count errors"
done

# Most common error messages
journalctl -p err --no-pager | grep -oP 'MESSAGE=\K.*' | sort | uniq -c | sort -rn | head -20

Pattern Detection

# Find recurring issues
cat > /usr/local/bin/analyze-patterns.sh << 'EOF'
#!/bin/bash
# Analyze log patterns

echo "=== System Error Patterns ==="
journalctl -p err --since "1 week ago" --no-pager | \
    grep -oP 'MESSAGE=\K.*' | \
    sed 's/[0-9]\+/NUM/g' | \
    sort | uniq -c | sort -rn | head -20

echo -e "\n=== Failed Services ==="
journalctl --since "1 week ago" --no-pager | \
    grep "Failed to start" | \
    grep -oP 'Failed to start \K.*' | \
    sort | uniq -c | sort -rn

echo -e "\n=== Authentication Failures by IP ==="
journalctl _SYSTEMD_UNIT=sshd.service --since "1 week ago" --no-pager | \
    grep "Failed password" | \
    grep -oP 'from \K[0-9.]+' | \
    sort | uniq -c | sort -rn | head -20
EOF

chmod +x /usr/local/bin/analyze-patterns.sh

Integration with Other Tools

Exporting for Analysis

# Export to CSV for analysis
cat > /usr/local/bin/export-logs-csv.sh << 'EOF'
#!/bin/bash
# Export logs to CSV format

echo "timestamp,priority,unit,message" > logs.csv
journalctl -o json --since today --no-pager | \
    jq -r '. | [.__REALTIME_TIMESTAMP, .PRIORITY, ._SYSTEMD_UNIT, .MESSAGE] | @csv' >> logs.csv
EOF

chmod +x /usr/local/bin/export-logs-csv.sh

# Export specific timeframe
journalctl --since "2024-07-19 00:00" --until "2024-07-19 23:59" -o export > daily_logs.export

# Convert to syslog format
journalctl -o short --no-pager > syslog_format.log

Remote Logging

# Configure remote logging
cat >> /etc/systemd/journald.conf << 'EOF'
[Journal]
ForwardToSyslog=yes
MaxLevelSyslog=debug
EOF

# Configure rsyslog forwarding
cat > /etc/rsyslog.d/remote.conf << 'EOF'
# Forward all logs to remote server
*.* @@remote-log-server:514

# Forward only errors
*.err @@remote-log-server:514
EOF

# Systemd-journal-remote setup
sudo dnf install systemd-journal-gateway

# Configure journal upload
cat > /etc/systemd/journal-upload.conf << 'EOF'
[Upload]
URL=https://journal-server:19532
ServerKeyFile=/etc/ssl/private/journal-upload.key
ServerCertificateFile=/etc/ssl/certs/journal-upload.pem
TrustedCertificateFile=/etc/ssl/certs/ca.pem
EOF

Troubleshooting with journalctl

Boot Issues

# Analyze boot time
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain

# Check for boot errors
journalctl -b -p err

# Failed services during boot
journalctl -b -u systemd-modules-load
systemctl --failed

# Kernel issues during boot
journalctl -b -k -p err

# Boot process timeline
journalctl -b -o short-monotonic

Service Troubleshooting

# Why service failed
systemctl status problematic.service
journalctl -u problematic.service -p err

# Service start attempts
journalctl -u nginx.service | grep -E "(Starting|Started|Failed)"

# Service dependencies
systemctl list-dependencies nginx.service
journalctl -u nginx.service --catalog

# Detailed service debugging
systemctl edit problematic.service
# Add under [Service]:
# Environment="SYSTEMD_LOG_LEVEL=debug"

# View service logs with context
journalctl -u httpd.service --since "5 minutes ago" -p debug

Performance Issues

# High CPU usage investigation
journalctl -f _TRANSPORT=kernel | grep -i cpu

# Memory issues
journalctl | grep -i "out of memory"
journalctl -k | grep -i "oom-killer"

# Disk I/O issues
journalctl -u systemd-journald | grep -i "failed to write"
journalctl | grep -i "i/o error"

# Network issues
journalctl -u NetworkManager -p err
journalctl | grep -i "link down\|link up"

Security Auditing

Authentication Monitoring

# All authentication attempts
journalctl -t sshd -t login -t systemd-logind

# Failed SSH attempts
journalctl _SYSTEMD_UNIT=sshd.service | grep "Failed password"

# Successful logins
journalctl _SYSTEMD_UNIT=sshd.service | grep "Accepted"

# Sudo usage
journalctl _COMM=sudo

# User account changes
journalctl -u systemd-logind | grep -E "(New user|User logged|Session opened)"

# SELinux denials
journalctl _TRANSPORT=audit | grep -i denied

Security Event Analysis

# Create security monitoring script
cat > /usr/local/bin/security-audit.sh << 'EOF'
#!/bin/bash
# Security audit script using journalctl

REPORT="/var/log/security-audit-$(date +%Y%m%d).log"

echo "Security Audit Report - $(date)" > $REPORT
echo "=================================" >> $REPORT

echo -e "\n[Failed Login Attempts]" >> $REPORT
journalctl --since today _SYSTEMD_UNIT=sshd.service | \
    grep "Failed password" | wc -l >> $REPORT

echo -e "\n[Successful Root Logins]" >> $REPORT
journalctl --since today _UID=0 | \
    grep "session opened" >> $REPORT

echo -e "\n[Sudo Commands Executed]" >> $REPORT
journalctl --since today _COMM=sudo | \
    grep COMMAND >> $REPORT

echo -e "\n[SELinux Denials]" >> $REPORT
journalctl --since today | \
    grep -i "avc:.*denied" >> $REPORT

echo -e "\n[System Reboots]" >> $REPORT
journalctl --list-boots | tail -5 >> $REPORT

echo -e "\n[Service Failures]" >> $REPORT
journalctl --since today -p err _TRANSPORT=systemd >> $REPORT

mail -s "Daily Security Audit - $(hostname)" [email protected] < $REPORT
EOF

chmod +x /usr/local/bin/security-audit.sh

Custom Log Integration

Application Logging

# Send custom logs to journal
echo "Application started" | systemd-cat -t myapp -p info

# With priority
echo "Critical error occurred" | systemd-cat -t myapp -p err

# From script
cat > /usr/local/bin/myapp.sh << 'EOF'
#!/bin/bash
# Application with journal logging

APP_NAME="myapp"

log_info() {
    echo "$1" | systemd-cat -t $APP_NAME -p info
}

log_error() {
    echo "$1" | systemd-cat -t $APP_NAME -p err
}

log_debug() {
    echo "$1" | systemd-cat -t $APP_NAME -p debug
}

# Application logic
log_info "Application starting..."
if ! do_something; then
    log_error "Failed to do something"
    exit 1
fi
log_info "Application completed successfully"
EOF

# Python logging to journal
cat > log_to_journal.py << 'EOF'
#!/usr/bin/env python3
from systemd import journal

# Simple logging
journal.write("Hello from Python app")

# With priority and fields
journal.send(
    "Application error occurred",
    PRIORITY=journal.Priority.ERROR,
    MY_APP_FIELD="custom_value",
    SYSLOG_IDENTIFIER="python_app"
)
EOF

Structured Logging

# Send structured data
systemd-cat -t myapp << EOF
MESSAGE=Application event occurred
PRIORITY=6
MY_CUSTOM_FIELD=value123
REQUEST_ID=abc-123-def
USER_ID=1000
EOF

# From application
logger -t myapp --journal "MESSAGE=User login" "USER_ID=1000" "SESSION_ID=xyz789"

# Query structured data
journalctl MY_CUSTOM_FIELD=value123
journalctl REQUEST_ID=abc-123-def

Performance Optimization

Query Optimization

# Use specific time ranges
journalctl --since "10 minutes ago" --until now

# Limit output size
journalctl -n 1000 --no-pager

# Use indexes efficiently
journalctl -u specific.service  # Faster than grep

# Export for external processing
journalctl -o export | process_logs

# Avoid excessive regex
journalctl _SYSTEMD_UNIT=sshd.service  # Better than grep

Resource Management

# Monitor journal performance
systemctl status systemd-journald
journalctl -u systemd-journald

# Check journal I/O
iotop -p $(pgrep systemd-journal)

# Limit journal CPU usage
systemctl edit systemd-journald
# Add:
# [Service]
# CPUQuota=20%

# Optimize for specific use cases
# For high-volume logging:
cat >> /etc/systemd/journald.conf << 'EOF'
RateLimitIntervalSec=0
RateLimitBurst=0
SyncIntervalSec=5m
EOF

Best Practices

1. Regular Maintenance

# Create maintenance script
cat > /usr/local/bin/journal-maintenance.sh << 'EOF'
#!/bin/bash
# Journal maintenance script

echo "Starting journal maintenance - $(date)"

# Rotate logs
journalctl --rotate

# Vacuum old logs
journalctl --vacuum-time=1month

# Verify integrity
journalctl --verify

# Check disk usage
echo "Current journal disk usage:"
journalctl --disk-usage

# Archive old logs if needed
if [ -d /var/log/journal ]; then
    find /var/log/journal -name "*.journal" -mtime +90 -exec gzip {} \;
fi

echo "Journal maintenance completed - $(date)"
EOF

chmod +x /usr/local/bin/journal-maintenance.sh

# Add to cron
echo "0 2 * * 0 /usr/local/bin/journal-maintenance.sh" | crontab -

2. Monitoring Setup

# Create comprehensive monitoring
cat > /usr/local/bin/log-monitor.sh << 'EOF'
#!/bin/bash
# Continuous log monitoring

monitor_errors() {
    journalctl -f -p err --no-pager | while read line; do
        echo "[ERROR] $line" | tee -a /var/log/monitor-errors.log
        # Alert on critical errors
        if echo "$line" | grep -q "CRITICAL\|FATAL\|PANIC"; then
            echo "$line" | mail -s "Critical Error on $(hostname)" [email protected]
        fi
    done
}

monitor_security() {
    journalctl -f | grep -E "(Failed password|authentication failure|unauthorized)" | \
    while read line; do
        echo "[SECURITY] $line" | tee -a /var/log/monitor-security.log
    done
}

# Run monitors in background
monitor_errors &
monitor_security &

wait
EOF

chmod +x /usr/local/bin/log-monitor.sh

3. Documentation

# Document important queries
cat > /etc/journalctl-queries.md << 'EOF'
# Common journalctl Queries

## System Health
- Recent errors: `journalctl -p err --since "1 hour ago"`
- Failed services: `systemctl --failed`
- Boot issues: `journalctl -b -p err`

## Security
- Failed logins: `journalctl _SYSTEMD_UNIT=sshd.service | grep Failed`
- Sudo usage: `journalctl _COMM=sudo`
- SELinux denials: `journalctl | grep "avc:.*denied"`

## Performance
- Slow boot: `systemd-analyze blame`
- High load: `journalctl --since "1 hour ago" | grep -i "high load"`
- OOM events: `journalctl -k | grep -i oom-killer`

## Application Specific
- Web server: `journalctl -u httpd -u nginx --since today`
- Database: `journalctl -u mariadb -u postgresql --since today`
- Custom app: `journalctl -t myapp --since today`
EOF

Conclusion

The journalctl command and systemd journal provide powerful capabilities for log management in AlmaLinux. From basic log viewing to advanced filtering and analysis, mastering journalctl is essential for effective system administration, troubleshooting, and security monitoring.

Key takeaways:

  • Use appropriate filters to find relevant information quickly
  • Configure persistence and rotation based on your needs
  • Implement regular monitoring and maintenance procedures
  • Leverage structured logging for better analysis
  • Combine journalctl with other tools for comprehensive monitoring

With these skills, you can efficiently manage system logs, quickly diagnose issues, and maintain comprehensive audit trails for your AlmaLinux systems.