日志分析脚本#

脚本说明#

日志分析脚本用于分析系统日志文件,提取关键信息,统计错误和警告,生成分析报告。

脚本代码#

#!/bin/bash

# 日志分析脚本
# 功能:分析系统日志文件,提取关键信息
# 作者:System Admin
# 日期:2026-01-01

set -euo pipefail

# 配置变量
LOG_FILE="/var/log/syslog"
OUTPUT_DIR="/tmp/log_analysis"
ANALYSIS_DATE=$(date +%Y%m%d)
REPORT_FILE="$OUTPUT_DIR/log_report_$ANALYSIS_DATE.txt"
ERROR_LOG="$OUTPUT_DIR/errors_$ANALYSIS_DATE.txt"
WARNING_LOG="$OUTPUT_DIR/warnings_$ANALYSIS_DATE.txt"
STATS_FILE="$OUTPUT_DIR/stats_$ANALYSIS_DATE.txt"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 日志函数
log() {
    local level=$1
    shift
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $@"
}

log_info() {
    log "INFO" "$@"
}

log_error() {
    log "ERROR" "$@"
}

log_warning() {
    log "WARNING" "$@"
}

# 检查日志文件
check_log_file() {
    if [ ! -f "$LOG_FILE" ]; then
        log_error "日志文件不存在: $LOG_FILE"
        return 1
    fi
    
    if [ ! -r "$LOG_FILE" ]; then
        log_error "日志文件不可读: $LOG_FILE"
        return 1
    fi
    
    return 0
}

# 创建输出目录
create_output_dir() {
    if [ ! -d "$OUTPUT_DIR" ]; then
        mkdir -p "$OUTPUT_DIR"
        log_info "创建输出目录: $OUTPUT_DIR"
    fi
}

# 统计日志级别
analyze_log_levels() {
    log_info "分析日志级别"
    
    {
        echo "日志级别统计"
        echo "================"
        echo ""
        
        # 统计各级别日志数量
        echo "ERROR: $(grep -c "ERROR" "$LOG_FILE" 2>/dev/null || echo 0)"
        echo "WARNING: $(grep -c "WARNING" "$LOG_FILE" 2>/dev/null || echo 0)"
        echo "INFO: $(grep -c "INFO" "$LOG_FILE" 2>/dev/null || echo 0)"
        echo "DEBUG: $(grep -c "DEBUG" "$LOG_FILE" 2>/dev/null || echo 0)"
        echo ""
        
        # 显示各级别日志的百分比
        local total=$(wc -l < "$LOG_FILE")
        echo "总行数: $total"
        echo ""
        
        echo "日志级别分布:"
        local error_count=$(grep -c "ERROR" "$LOG_FILE" 2>/dev/null || echo 0)
        local warning_count=$(grep -c "WARNING" "$LOG_FILE" 2>/dev/null || echo 0)
        local info_count=$(grep -c "INFO" "$LOG_FILE" 2>/dev/null || echo 0)
        local debug_count=$(grep -c "DEBUG" "$LOG_FILE" 2>/dev/null || echo 0)
        
        echo "ERROR: $(awk "BEGIN {printf \"%.2f\", ($error_count/$total)*100}")%"
        echo "WARNING: $(awk "BEGIN {printf \"%.2f\", ($warning_count/$total)*100}")%"
        echo "INFO: $(awk "BEGIN {printf \"%.2f\", ($info_count/$total)*100}")%"
        echo "DEBUG: $(awk "BEGIN {printf \"%.2f\", ($debug_count/$total)*100}")%"
    } > "$STATS_FILE"
    
    log_info "日志级别统计完成: $STATS_FILE"
}

# 提取错误日志
extract_errors() {
    log_info "提取错误日志"
    
    {
        echo "错误日志"
        echo "======="
        echo ""
        echo "生成时间: $(date)"
        echo ""
        
        # 提取所有错误
        grep "ERROR" "$LOG_FILE" | \
            awk '{print NR": "$0}' | \
            tail -50
        
        echo ""
        echo "错误统计:"
        echo "总错误数: $(grep -c "ERROR" "$LOG_FILE" 2>/dev/null || echo 0)"
        
        # 统计错误类型
        echo ""
        echo "错误类型统计:"
        grep "ERROR" "$LOG_FILE" 2>/dev/null | \
            awk '{print $NF}' | \
            sort | \
            uniq -c | \
            sort -nr | \
            head -20
    } > "$ERROR_LOG"
    
    log_info "错误日志提取完成: $ERROR_LOG"
}

# 提取警告日志
extract_warnings() {
    log_info "提取警告日志"
    
    {
        echo "警告日志"
        echo "======="
        echo ""
        echo "生成时间: $(date)"
        echo ""
        
        # 提取所有警告
        grep "WARNING" "$LOG_FILE" | \
            awk '{print NR": "$0}' | \
            tail -50
        
        echo ""
        echo "警告统计:"
        echo "总警告数: $(grep -c "WARNING" "$LOG_FILE" 2>/dev/null || echo 0)"
        
        # 统计警告类型
        echo ""
        echo "警告类型统计:"
        grep "WARNING" "$LOG_FILE" 2>/dev/null | \
            awk '{print $NF}' | \
            sort | \
            uniq -c | \
            sort -nr | \
            head -20
    } > "$WARNING_LOG"
    
    log_info "警告日志提取完成: $WARNING_LOG"
}

# 分析服务日志
analyze_services() {
    log_info "分析服务日志"
    
    {
        echo "服务日志分析"
        echo "============"
        echo ""
        
        # 分析常见服务
        local services=("nginx" "apache" "mysql" "ssh" "cron" "systemd")
        
        for service in "${services[@]}"; do
            local count=$(grep -c "$service" "$LOG_FILE" 2>/dev/null || echo 0)
            if [ $count -gt 0 ]; then
                echo "服务: $service"
                echo "日志数量: $count"
                echo "最近日志:"
                grep "$service" "$LOG_FILE" | tail -5
                echo ""
            fi
        done
    } >> "$REPORT_FILE"
}

# 分析时间分布
analyze_time_distribution() {
    log_info "分析时间分布"
    
    {
        echo "时间分布分析"
        echo "============"
        echo ""
        
        # 按小时统计
        echo "按小时统计:"
        awk '{print substr($3,1,2)}' "$LOG_FILE" | \
            sort | \
            uniq -c | \
            sort -n
        
        echo ""
        
        # 按日期统计
        echo "按日期统计:"
        awk '{print $1, $2}' "$LOG_FILE" | \
            sort | \
            uniq -c | \
            sort -n
    } >> "$REPORT_FILE"
}

# 分析IP地址
analyze_ip_addresses() {
    log_info "分析IP地址"
    
    {
        echo "IP地址分析"
        echo "==========="
        echo ""
        
        # 提取IP地址
        grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' "$LOG_FILE" | \
            sort | \
            uniq -c | \
            sort -nr | \
            head -20
    } >> "$REPORT_FILE"
}

# 分析用户活动
analyze_user_activity() {
    log_info "分析用户活动"
    
    {
        echo "用户活动分析"
        echo "==========="
        echo ""
        
        # 提取用户名
        grep -oE 'user[[:space:]]+[a-zA-Z0-9_]+' "$LOG_FILE" | \
            awk '{print $2}' | \
            sort | \
            uniq -c | \
            sort -nr | \
            head -20
    } >> "$REPORT_FILE"
}

# 查找异常模式
find_anomalies() {
    log_info "查找异常模式"
    
    {
        echo "异常模式检测"
        echo "==========="
        echo ""
        
        # 查找失败登录
        echo "失败登录尝试:"
        grep -i "failed login\|authentication failure" "$LOG_FILE" | \
            tail -20
        
        echo ""
        
        # 查找连接超时
        echo "连接超时:"
        grep -i "timeout\|connection refused" "$LOG_FILE" | \
            tail -20
        
        echo ""
        
        # 查找磁盘错误
        echo "磁盘错误:"
        grep -i "disk error\|i/o error" "$LOG_FILE" | \
            tail -20
    } >> "$REPORT_FILE"
}

# 生成趋势分析
generate_trend_analysis() {
    log_info "生成趋势分析"
    
    {
        echo "趋势分析"
        echo "========"
        echo ""
        
        # 错误趋势
        echo "错误趋势(最近24小时):"
        local current_hour=$(date +%H)
        for ((i=0; i<24; i++)); do
            local hour=$(( (current_hour - i + 24) % 24 ))
            local count=$(awk -v h="$hour" '$3 ~ "^"h":" {count++} END {print count+0}' "$LOG_FILE" 2>/dev/null || echo 0)
            printf "%02d:00 - %d\n" "$hour" "$count"
        done | sort -n
        
        echo ""
        
        # 警告趋势
        echo "警告趋势(最近24小时):"
        for ((i=0; i<24; i++)); do
            local hour=$(( (current_hour - i + 24) % 24 ))
            local count=$(awk -v h="$hour" '$3 ~ "^"h":" && /WARNING/ {count++} END {print count+0}' "$LOG_FILE" 2>/dev/null || echo 0)
            printf "%02d:00 - %d\n" "$hour" "$count"
        done | sort -n
    } >> "$REPORT_FILE"
}

# 生成分析报告
generate_report() {
    log_info "生成分析报告"
    
    {
        echo "日志分析报告"
        echo "============"
        echo ""
        echo "日志文件: $LOG_FILE"
        echo "分析时间: $(date)"
        echo "报告文件: $REPORT_FILE"
        echo ""
        echo "======================================"
        echo ""
        
        # 日志文件信息
        echo "日志文件信息"
        echo "============"
        echo "文件大小: $(du -h "$LOG_FILE" | cut -f1)"
        echo "总行数: $(wc -l < "$LOG_FILE")"
        echo "文件权限: $(ls -l "$LOG_FILE" | awk '{print $1}')"
        echo "修改时间: $(ls -l "$LOG_FILE" | awk '{print $6, $7, $8}')"
        echo ""
        
        # 包含其他分析结果
        cat "$STATS_FILE"
        echo ""
        
        # 服务分析
        analyze_services
        echo ""
        
        # 时间分布
        analyze_time_distribution
        echo ""
        
        # IP地址分析
        analyze_ip_addresses
        echo ""
        
        # 用户活动分析
        analyze_user_activity
        echo ""
        
        # 异常模式
        find_anomalies
        echo ""
        
        # 趋势分析
        generate_trend_analysis
        echo ""
        
        # 总结
        echo "总结"
        echo "===="
        local total_errors=$(grep -c "ERROR" "$LOG_FILE" 2>/dev/null || echo 0)
        local total_warnings=$(grep -c "WARNING" "$LOG_FILE" 2>/dev/null || echo 0)
        echo "总错误数: $total_errors"
        echo "总警告数: $total_warnings"
        
        if [ $total_errors -gt 100 ]; then
            echo "警告: 错误数量过多,建议检查系统状态"
        fi
        
        if [ $total_warnings -gt 500 ]; then
            echo "注意: 警告数量较多,建议关注系统性能"
        fi
    } > "$REPORT_FILE"
    
    log_info "分析报告生成完成: $REPORT_FILE"
}

# 显示摘要
show_summary() {
    echo -e "${GREEN}===== 日志分析完成 =====${NC}"
    echo ""
    echo "分析文件: $LOG_FILE"
    echo "输出目录: $OUTPUT_DIR"
    echo ""
    echo "生成的文件:"
    echo "  - 分析报告: $REPORT_FILE"
    echo "  - 错误日志: $ERROR_LOG"
    echo "  - 警告日志: $WARNING_LOG"
    echo "  - 统计信息: $STATS_FILE"
    echo ""
    
    local total_errors=$(grep -c "ERROR" "$LOG_FILE" 2>/dev/null || echo 0)
    local total_warnings=$(grep -c "WARNING" "$LOG_FILE" 2>/dev/null || echo 0)
    
    echo -e "总错误数: ${RED}$total_errors${NC}"
    echo -e "总警告数: ${YELLOW}$total_warnings${NC}"
    echo ""
    
    if [ $total_errors -gt 0 ]; then
        echo -e "${RED}建议: 检查错误日志文件${NC}"
    fi
    
    if [ $total_warnings -gt 0 ]; then
        echo -e "${YELLOW}建议: 检查警告日志文件${NC}"
    fi
}

# 主函数
main() {
    log_info "===== 开始日志分析 ====="
    
    # 检查日志文件
    if ! check_log_file; then
        exit 1
    fi
    
    # 创建输出目录
    create_output_dir
    
    # 执行分析
    analyze_log_levels
    extract_errors
    extract_warnings
    generate_report
    
    # 显示摘要
    show_summary
    
    log_info "===== 日志分析完成 ====="
}

# 参数解析
while getopts "l:o:h" opt; do
    case $opt in
        l)
            LOG_FILE="$OPTARG"
            log_info "日志文件: $LOG_FILE"
            ;;
        o)
            OUTPUT_DIR="$OPTARG"
            log_info "输出目录: $OUTPUT_DIR"
            ;;
        h)
            echo "用法: $0 [选项]"
            echo "选项:"
            echo "  -l <日志文件>  指定日志文件(默认: /var/log/syslog)"
            echo "  -o <输出目录>  指定输出目录(默认: /tmp/log_analysis)"
            echo "  -h            显示帮助信息"
            exit 0
            ;;
        *)
            echo "无效选项: $opt"
            exit 1
            ;;
    esac
done

# 执行主函数
main "$@"

使用说明#

  1. 添加执行权限:

    chmod +x log_analyzer.sh
  2. 基本用法:

    # 分析系统日志
    ./log_analyzer.sh
    
    # 分析指定日志文件
    ./log_analyzer.sh -l /var/log/nginx/access.log
    
    # 指定输出目录
    ./log_analyzer.sh -o /home/user/log_analysis
  3. 查看结果:

    # 查看分析报告
    cat /tmp/log_analysis/log_report_*.txt
    
    # 查看错误日志
    cat /tmp/log_analysis/errors_*.txt
    
    # 查看警告日志
    cat /tmp/log_analysis/warnings_*.txt

功能特点#

  • 日志级别统计
  • 错误和警告提取
  • 服务日志分析
  • 时间分布分析
  • IP地址分析
  • 用户活动分析
  • 异常模式检测
  • 趋势分析
  • 详细的分析报告

依赖项#

  • grep: 用于文本搜索
  • awk: 用于文本处理
  • sort: 用于排序
  • uniq: 用于去重统计

注意事项#

  1. 需要读取日志文件的权限
  2. 大日志文件分析可能需要较长时间
  3. 输出目录需要有写入权限
  4. 定期清理旧的输出文件
  5. 根据实际日志格式调整分析逻辑