journalctl 命令详解#

journalctl 是 Linux 系统中用于查询和显示 systemd 日志的命令。它可以查看系统日志、服务日志、内核日志等,支持多种过滤和格式化选项,是系统管理员进行日志管理和故障排查的重要工具。

入门#

基本用法#

# 显示所有日志
journalctl

# 显示最近的日志
journalctl -n

# 实时跟踪日志
journalctl -f

# 显示系统启动日志
journalctl -b

常用选项#

选项说明
-b显示当前启动的日志
-f实时跟踪日志
-n显示最近的日志
-r反向显示日志
-e跳转到日志末尾
-k显示内核日志
-u显示特定单元的日志

基本示例#

# 显示所有日志
journalctl

# 输出示例:
# -- Logs begin at Mon 2024-01-01 00:00:00 CST, end at Mon 2024-01-01 10:00:00 CST. --
# Jan 01 00:00:00 localhost systemd[1]: Started User Manager for UID 1000.
# Jan 01 00:00:01 localhost sshd[1234]: Accepted password for user from 192.168.1.100 port 22
# Jan 01 00:00:02 localhost nginx[5678]: worker process started

# 显示最近的 10 条日志
journalctl -n 10

# 实时跟踪日志
journalctl -f

# 显示系统启动日志
journalctl -b

中级#

日志过滤#

# 显示特定单元的日志
journalctl -u nginx

# 显示特定优先级的日志
journalctl -p err

# 显示特定时间范围的日志
journalctl --since "2024-01-01 00:00:00"
journalctl --until "2024-01-01 10:00:00"

# 显示特定用户的日志
journalctl _UID=1000

# 显示特定进程的日志
journalctl _PID=1234

日志格式化#

# 以 JSON 格式显示
journalctl -o json

# 以短格式显示
journalctl -o short

# 以详细格式显示
journalctl -o verbose

# 以 cat 格式显示(不显示时间戳)
journalctl -o cat

# 以 JSON-pretty 格式显示
journalctl -o json-pretty

日志搜索#

# 搜索包含特定关键词的日志
journalctl | grep "error"

# 搜索特定单元的日志
journalctl -u nginx | grep "error"

# 搜索特定优先级的日志
journalctl -p err | grep "nginx"

# 反向搜索
journalctl -r | grep "error"

# 搜索并显示上下文
journalctl -n 20 | grep -C 5 "error"

高级#

高级过滤#

# 组合过滤条件
journalctl -u nginx -p err --since "2024-01-01"

# 显示特定标识符的日志
journalctl _SYSTEMD_UNIT=nginx.service

# 显示特定优先级及以上的日志
journalctl -p err..alert

# 显示特定优先级范围的日志
journalctl -p 0..3

# 显示特定引导的日志
journalctl -b -1

日志管理#

# 显示日志大小
journalctl --disk-usage

# 清理旧日志
journalctl --vacuum-time=7d

# 清理到特定大小
journalctl --vacuum-size=1G

# 清理到特定条目数
journalctl --vacuum-files=10

# 显示日志配置
journalctl --header

日志导出#

# 导出日志到文件
journalctl > /tmp/journal.log

# 导出特定时间范围的日志
journalctl --since "2024-01-01" --until "2024-01-02" > /tmp/journal.log

# 导出特定单元的日志
journalctl -u nginx > /tmp/nginx.log

# 导出为 JSON 格式
journalctl -o json > /tmp/journal.json

# 导出为二进制格式
journalctl --output=export > /tmp/journal.export

大师#

日志分析脚本#

#!/bin/bash
# 日志分析脚本

UNIT=$1
LOG_FILE="log_analysis_$(date +%Y%m%d_%H%M%S).txt"

# 分析单元日志
analyze_unit_logs() {
    local unit=$1
    
    echo "=== Log Analysis for $unit ===" > $LOG_FILE
    echo "Analysis Time: $(date)" >> $LOG_FILE
    echo "" >> $LOG_FILE
    
    # 日志统计
    echo "=== Log Statistics ===" >> $LOG_FILE
    echo "Total entries: $(journalctl -u $unit --no-pager | wc -l)" >> $LOG_FILE
    echo "" >> $LOG_FILE
    
    # 错误日志
    echo "=== Error Logs ===" >> $LOG_FILE
    journalctl -u $unit -p err --no-pager >> $LOG_FILE
    echo "" >> $LOG_FILE
    
    # 警告日志
    echo "=== Warning Logs ===" >> $LOG_FILE
    journalctl -u $unit -p warning --no-pager >> $LOG_FILE
    echo "" >> $LOG_FILE
    
    # 最近的日志
    echo "=== Recent Logs (last 20) ===" >> $LOG_FILE
    journalctl -u $unit -n 20 --no-pager >> $LOG_FILE
    
    echo "Analysis saved to: $LOG_FILE"
}

# 分析错误日志
analyze_error_logs() {
    echo "=== Error Log Analysis ==="
    echo ""
    
    # 所有错误日志
    echo "All error logs:"
    journalctl -p err --no-pager
    echo ""
    
    # 按单元分组
    echo "Error logs by unit:"
    journalctl -p err --no-pager | awk '{print $5}' | sort | uniq -c | sort -rn
}

# 分析特定时间范围的日志
analyze_time_range() {
    local start_time=$1
    local end_time=$2
    
    echo "=== Log Analysis for Time Range ==="
    echo "Start: $start_time"
    echo "End: $end_time"
    echo ""
    
    journalctl --since "$start_time" --until "$end_time" --no-pager
}

# 主函数
main() {
    case "$1" in
        unit)
            analyze_unit_logs "$2"
            ;;
        errors)
            analyze_error_logs
            ;;
        time)
            analyze_time_range "$2" "$3"
            ;;
        *)
            echo "Usage: $0 {unit|errors|time}"
            exit 1
            ;;
    esac
}

main "$@"

日志监控脚本#

#!/bin/bash
# 日志监控脚本

UNIT=$1
ALERT_KEYWORD=$2
ALERT_EMAIL="admin@example.com"

# 监控单元日志
monitor_unit_logs() {
    local unit=$1
    local keyword=$2
    
    echo "Monitoring logs for $unit..."
    
    journalctl -u $unit -f | while read line; do
        if echo "$line" | grep -q "$keyword"; then
            echo "ALERT: Found keyword '$keyword' in logs"
            echo "$line" | mail -s "Log Alert" $ALERT_EMAIL
        fi
    done
}

# 监控错误日志
monitor_error_logs() {
    echo "Monitoring error logs..."
    
    journalctl -p err -f | while read line; do
        echo "ERROR: $line"
        echo "$line" | mail -s "Error Log Alert" $ALERT_EMAIL
    done
}

# 监控特定关键词
monitor_keyword() {
    local keyword=$1
    
    echo "Monitoring logs for keyword: $keyword"
    
    journalctl -f | while read line; do
        if echo "$line" | grep -q "$keyword"; then
            echo "ALERT: Found keyword '$keyword' in logs"
            echo "$line" | mail -s "Log Alert" $ALERT_EMAIL
        fi
    done
}

# 主函数
main() {
    case "$1" in
        unit)
            monitor_unit_logs "$2" "$3"
            ;;
        errors)
            monitor_error_logs
            ;;
        keyword)
            monitor_keyword "$2"
            ;;
        *)
            echo "Usage: $0 {unit|errors|keyword}"
            exit 1
            ;;
    esac
}

main "$@"

日志清理脚本#

#!/bin/bash
# 日志清理脚本

# 清理旧日志
clean_old_logs() {
    local days=$1
    
    echo "Cleaning logs older than $days days..."
    journalctl --vacuum-time=${days}d
}

# 清理到特定大小
clean_logs_by_size() {
    local size=$1
    
    echo "Cleaning logs to size $size..."
    journalctl --vacuum-size=$size
}

# 清理到特定文件数
clean_logs_by_files() {
    local files=$1
    
    echo "Cleaning logs to $files files..."
    journalctl --vacuum-files=$files
}

# 显示日志使用情况
show_log_usage() {
    echo "=== Journal Disk Usage ==="
    journalctl --disk-usage
}

# 主函数
main() {
    case "$1" in
        time)
            clean_old_logs "$2"
            ;;
        size)
            clean_logs_by_size "$2"
            ;;
        files)
            clean_logs_by_files "$2"
            ;;
        usage)
            show_log_usage
            ;;
        *)
            echo "Usage: $0 {time|size|files|usage}"
            exit 1
            ;;
    esac
}

main "$@"

无敌#

企业级日志管理系统#

#!/bin/bash
# 企业级日志管理系统

CONFIG_FILE="/etc/log_manager/config.conf"
LOG_DIR="/var/log/log_manager"
ARCHIVE_DIR="/var/log/log_manager/archives"

mkdir -p $LOG_DIR $ARCHIVE_DIR

# 加载配置
source $CONFIG_FILE

# 收集日志
collect_logs() {
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local output_file="$LOG_DIR/journal_$timestamp.log"
    
    echo "Collecting logs to $output_file..."
    
    journalctl --since "yesterday" --no-pager > $output_file
    
    echo "Logs collected to: $output_file"
}

# 分析日志
analyze_logs() {
    local log_file=$1
    local analysis_file="$LOG_DIR/analysis_$(date +%Y%m%d_%H%M%S).txt"
    
    echo "=== Log Analysis ===" > $analysis_file
    echo "Log File: $log_file" >> $analysis_file
    echo "Analysis Time: $(date)" >> $analysis_file
    echo "" >> $analysis_file
    
    # 统计信息
    echo "=== Statistics ===" >> $analysis_file
    echo "Total entries: $(wc -l < $log_file)" >> $analysis_file
    echo "Error entries: $(grep -i error $log_file | wc -l)" >> $analysis_file
    echo "Warning entries: $(grep -i warning $log_file | wc -l)" >> $analysis_file
    echo "" >> $analysis_file
    
    # 错误日志
    echo "=== Error Logs ===" >> $analysis_file
    grep -i error $log_file >> $analysis_file
    echo "" >> $analysis_file
    
    # 警告日志
    echo "=== Warning Logs ===" >> $analysis_file
    grep -i warning $log_file >> $analysis_file
    
    echo "Analysis saved to: $analysis_file"
}

# 归档日志
archive_logs() {
    local archive_file="$ARCHIVE_DIR/journal_$(date +%Y%m%d).tar.gz"
    
    echo "Archiving logs to $archive_file..."
    
    tar -czf $archive_file $LOG_DIR/*.log
    
    echo "Logs archived to: $archive_file"
}

# 生成日志报告
generate_log_report() {
    local report_file="$LOG_DIR/log_report_$(date +%Y%m%d).txt"
    
    echo "Log Report - $(date +%Y-%m-%d)" > $report_file
    echo "=============" >> $report_file
    echo "" >> $report_file
    
    # 日志使用情况
    echo "=== Journal Disk Usage ===" >> $report_file
    journalctl --disk-usage >> $report_file
    echo "" >> $report_file
    
    # 错误日志统计
    echo "=== Error Log Statistics ===" >> $report_file
    echo "Total errors: $(journalctl -p err --no-pager | wc -l)" >> $report_file
    echo "" >> $report_file
    
    # 按单元分组的错误
    echo "=== Errors by Unit ===" >> $report_file
    journalctl -p err --no-pager | awk '{print $5}' | sort | uniq -c | sort -rn >> $report_file
    echo "" >> $report_file
    
    # 最近的错误
    echo "=== Recent Errors ===" >> $report_file
    journalctl -p err -n 20 --no-pager >> $report_file
    
    echo "Report saved to: $report_file"
}

# 主函数
main() {
    case "$1" in
        collect)
            collect_logs
            ;;
        analyze)
            analyze_logs "$2"
            ;;
        archive)
            archive_logs
            ;;
        report)
            generate_log_report
            ;;
        *)
            echo "Usage: $0 {collect|analyze|archive|report}"
            exit 1
            ;;
    esac
}

main "$@"

智能日志分析系统#

#!/bin/bash
# 智能日志分析系统

CONFIG_FILE="/etc/log_analyzer/config.conf"
LOG_DIR="/var/log/log_analyzer"
ALERT_LOG="/var/log/log_analyzer/alerts.log"

mkdir -p $LOG_DIR $(dirname $ALERT_LOG)

# 加载配置
source $CONFIG_FILE

# 分析日志模式
analyze_log_patterns() {
    local log_file=$1
    local pattern_file="$LOG_DIR/patterns_$(date +%Y%m%d_%H%M%S).txt"
    
    echo "=== Log Pattern Analysis ===" > $pattern_file
    echo "Log File: $log_file" >> $pattern_file
    echo "Analysis Time: $(date)" >> $pattern_file
    echo "" >> $pattern_file
    
    # 错误模式
    echo "=== Error Patterns ===" >> $pattern_file
    grep -i "error" $log_file | sed 's/.*error: //' | sort | uniq -c | sort -rn >> $pattern_file
    echo "" >> $pattern_file
    
    # 警告模式
    echo "=== Warning Patterns ===" >> $pattern_file
    grep -i "warning" $log_file | sed 's/.*warning: //' | sort | uniq -c | sort -rn >> $pattern_file
    echo "" >> $pattern_file
    
    # 失败模式
    echo "=== Failure Patterns ===" >> $pattern_file
    grep -i "failed" $log_file | sed 's/.*failed: //' | sort | uniq -c | sort -rn >> $pattern_file
    
    echo "Pattern analysis saved to: $pattern_file"
}

# 检测异常日志
detect_anomalies() {
    local log_file=$1
    local anomaly_file="$LOG_DIR/anomalies_$(date +%Y%m%d_%H%M%S).txt"
    
    echo "=== Anomaly Detection ===" > $anomaly_file
    echo "Log File: $log_file" >> $anomaly_file
    echo "Detection Time: $(date)" >> $anomaly_file
    echo "" >> $anomaly_file
    
    # 检测频繁错误
    echo "=== Frequent Errors ===" >> $anomaly_file
    grep -i "error" $log_file | sed 's/.*error: //' | sort | uniq -c | sort -rn | awk '$1 > 10 {print $0}' >> $anomaly_file
    echo "" >> $anomaly_file
    
    # 检测关键错误
    echo "=== Critical Errors ===" >> $anomaly_file
    grep -i "critical\|fatal\|panic" $log_file >> $anomaly_file
    echo "" >> $anomaly_file
    
    # 检测认证失败
    echo "=== Authentication Failures ===" >> $anomaly_file
    grep -i "authentication failed\|login failed" $log_file >> $anomaly_file
    
    echo "Anomaly detection saved to: $anomaly_file"
}

# 生成分析报告
generate_analysis_report() {
    local report_file="$LOG_DIR/analysis_report_$(date +%Y%m%d).txt"
    
    echo "Log Analysis Report - $(date +%Y-%m-%d)" > $report_file
    echo "=====================" >> $report_file
    echo "" >> $report_file
    
    # 日志统计
    echo "=== Log Statistics ===" >> $report_file
    echo "Total entries: $(journalctl --since yesterday --no-pager | wc -l)" >> $report_file
    echo "Error entries: $(journalctl -p err --since yesterday --no-pager | wc -l)" >> $report_file
    echo "Warning entries: $(journalctl -p warning --since yesterday --no-pager | wc -l)" >> $report_file
    echo "" >> $report_file
    
    # 错误模式
    echo "=== Error Patterns ===" >> $report_file
    journalctl -p err --since yesterday --no-pager | sed 's/.*error: //' | sort | uniq -c | sort -rn | head -20 >> $report_file
    echo "" >> $report_file
    
    # 异常检测
    echo "=== Anomalies ===" >> $report_file
    journalctl -p crit --since yesterday --no-pager >> $report_file
    
    echo "Analysis report saved to: $report_file"
}

# 主函数
main() {
    case "$1" in
        patterns)
            analyze_log_patterns "$2"
            ;;
        anomalies)
            detect_anomalies "$2"
            ;;
        report)
            generate_analysis_report
            ;;
        *)
            echo "Usage: $0 {patterns|anomalies|report}"
            exit 1
            ;;
    esac
}

main "$@"

日志安全审计系统#

#!/bin/bash
# 日志安全审计系统

AUDIT_LOG="/var/log/log_audit/audit.log"
ALERT_LOG="/var/log/log_audit/alerts.log"

mkdir -p $(dirname $AUDIT_LOG) $(dirname $ALERT_LOG)

# 审计安全事件
audit_security_events() {
    echo "=== Security Event Audit ===" >> $AUDIT_LOG
    echo "Audit Time: $(date)" >> $AUDIT_LOG
    echo "" >> $AUDIT_LOG
    
    # 认证失败
    echo "Authentication Failures:" >> $AUDIT_LOG
    journalctl --since yesterday -p err --no-pager | grep -i "authentication failed\|login failed" >> $AUDIT_LOG
    echo "" >> $AUDIT_LOG
    
    # 权限拒绝
    echo "Permission Denied:" >> $AUDIT_LOG
    journalctl --since yesterday -p err --no-pager | grep -i "permission denied" >> $AUDIT_LOG
    echo "" >> $AUDIT_LOG
    
    # 访问拒绝
    echo "Access Denied:" >> $AUDIT_LOG
    journalctl --since yesterday -p err --no-pager | grep -i "access denied" >> $AUDIT_LOG
}

# 审计系统事件
audit_system_events() {
    echo "=== System Event Audit ===" >> $AUDIT_LOG
    echo "Audit Time: $(date)" >> $AUDIT_LOG
    echo "" >> $AUDIT_LOG
    
    # 服务启动/停止
    echo "Service Start/Stop Events:" >> $AUDIT_LOG
    journalctl --since yesterday -p notice --no-pager | grep -i "started\|stopped" >> $AUDIT_LOG
    echo "" >> $AUDIT_LOG
    
    # 系统重启
    echo "System Reboot Events:" >> $AUDIT_LOG
    journalctl --since yesterday -p notice --no-pager | grep -i "reboot\|shutdown" >> $AUDIT_LOG
    echo "" >> $AUDIT_LOG
    
    # 内核事件
    echo "Kernel Events:" >> $AUDIT_LOG
    journalctl --since yesterday -k --no-pager >> $AUDIT_LOG
}

# 检测安全威胁
detect_security_threats() {
    echo "=== Security Threat Detection ===" >> $ALERT_LOG
    echo "Detection Time: $(date)" >> $ALERT_LOG
    echo "" >> $ALERT_LOG
    
    # 暴力破解
    echo "Potential Brute Force Attacks:" >> $ALERT_LOG
    journalctl --since yesterday -p err --no-pager | grep -i "authentication failed" | awk '{print $5}' | sort | uniq -c | sort -rn | awk '$1 > 10 {print $0}' >> $ALERT_LOG
    echo "" >> $ALERT_LOG
    
    # 异常登录
    echo "Suspicious Login Attempts:" >> $ALERT_LOG
    journalctl --since yesterday -p err --no-pager | grep -i "invalid user\|failed password" >> $ALERT_LOG
    echo "" >> $ALERT_LOG
    
    # 权限提升
    echo "Privilege Escalation Attempts:" >> $ALERT_LOG
    journalctl --since yesterday -p err --no-pager | grep -i "sudo\|su" | grep -i "failed" >> $ALERT_LOG
}

# 生成审计报告
generate_audit_report() {
    local report_file="/var/log/log_audit/audit_report_$(date +%Y%m%d).txt"
    
    echo "Security Audit Report - $(date +%Y-%m-%d)" > $report_file
    echo "=========================" >> $report_file
    echo "" >> $report_file
    
    # 安全事件
    echo "=== Security Events ===" >> $report_file
    journalctl --since yesterday -p err --no-pager | grep -i "authentication failed\|permission denied" | head -50 >> $report_file
    echo "" >> $report_file
    
    # 系统事件
    echo "=== System Events ===" >> $report_file
    journalctl --since yesterday -p notice --no-pager | grep -i "started\|stopped" | head -50 >> $report_file
    echo "" >> $report_file
    
    # 威胁检测
    echo "=== Security Threats ===" >> $report_file
    journalctl --since yesterday -p crit --no-pager >> $report_file
    
    echo "Audit report saved to: $report_file"
}

# 主函数
main() {
    case "$1" in
        security)
            audit_security_events
            ;;
        system)
            audit_system_events
            ;;
        threats)
            detect_security_threats
            ;;
        report)
            generate_audit_report
            ;;
        *)
            echo "Usage: $0 {security|system|threats|report}"
            exit 1
            ;;
    esac
}

main "$@"

最佳实践#

  1. 定期检查日志:定期使用 journalctl 检查系统日志
  2. 关注错误和警告:优先查看错误和警告级别的日志
  3. 使用过滤选项:使用过滤选项快速定位问题
  4. 实时监控日志:使用 -f 选项实时监控日志
  5. 定期清理日志:定期清理旧日志,避免占用过多磁盘空间
  6. 导出重要日志:导出重要日志以便长期保存
  7. 分析日志模式:分析日志模式,发现潜在问题
  8. 设置日志告警:设置日志告警,及时发现异常

注意事项#

  • journalctl 需要 root 权限才能查看所有日志
  • 日志可能被配置为持久化或非持久化
  • 旧的日志可能会被自动清理
  • 实时监控日志会消耗系统资源
  • 日志文件可能很大,需要合理使用过滤选项
  • 在生产环境中清理日志时要格外小心
  • 注意日志的敏感信息,避免泄露
  • 对于关键业务,建议使用专业的日志管理工具
  • 日志的时间戳可能受系统时间影响