跳转到内容

日志分析脚本实战

课程介绍

日志分析是运维工作的重要组成部分,通过分析日志可以发现系统问题、优化系统性能。本课程将通过实战案例,带你学习如何编写日志分析脚本,包括日志统计、日志过滤、日志聚合等核心功能。

1. 日志分析概述

1.1 什么是日志分析

日志分析是指对日志文件进行分析,提取有价值的信息。

日志分析的目的

目的说明
故障排查发现和定位系统故障
性能优化分析系统性能瓶颈
安全审计检测安全威胁
业务分析分析业务数据

1.2 日志分析的方法

日志分析有多种方法。

分析方法

方法说明
统计分析统计日志的数量、频率等
过滤分析过滤特定的日志
聚合分析聚合相关的日志
趋势分析分析日志的趋势变化

2. 日志统计脚本

2.1 日志级别统计

统计不同日志级别的数量。

脚本

bash
#!/bin/bash
# 日志级别统计脚本

# 配置
LOG_FILE="/var/log/syslog"

# 统计日志级别
ERROR_COUNT=$(grep -c "ERROR" "$LOG_FILE")
WARN_COUNT=$(grep -c "WARN" "$LOG_FILE")
INFO_COUNT=$(grep -c "INFO" "$LOG_FILE")
DEBUG_COUNT=$(grep -c "DEBUG" "$LOG_FILE")

# 输出统计结果
echo "===== 日志级别统计 ====="
echo "ERROR数量:$ERROR_COUNT"
echo "WARN数量:$WARN_COUNT"
echo "INFO数量:$INFO_COUNT"
echo "DEBUG数量:$DEBUG_COUNT"
echo "总计:$((ERROR_COUNT + WARN_COUNT + INFO_COUNT + DEBUG_COUNT))"

使用方法

bash
# 赋予执行权限
chmod +x log_level_count.sh

# 执行脚本
./log_level_count.sh

2.2 日志频率统计

统计日志的频率。

脚本

bash
#!/bin/bash
# 日志频率统计脚本

# 配置
LOG_FILE="/var/log/syslog"

# 统计每小时的日志数量
echo "===== 日志频率统计(每小时)====="
awk '{print substr($1, 1, 13)}' "$LOG_FILE" | sort | uniq -c | sort -nr

# 统计每天的日志数量
echo "===== 日志频率统计(每天)====="
awk '{print substr($1, 1, 10)}' "$LOG_FILE" | sort | uniq -c | sort -nr

使用方法

bash
# 赋予执行权限
chmod +x log_frequency_count.sh

# 执行脚本
./log_frequency_count.sh

2.3 日志来源统计

统计日志的来源。

脚本

bash
#!/bin/bash
# 日志来源统计脚本

# 配置
LOG_FILE="/var/log/syslog"

# 统计日志来源
echo "===== 日志来源统计 ====="
awk '{print $5}' "$LOG_FILE" | sort | uniq -c | sort -nr

使用方法

bash
# 赋予执行权限
chmod +x log_source_count.sh

# 执行脚本
./log_source_count.sh

3. 日志过滤脚本

3.1 过滤错误日志

过滤ERROR级别的日志。

脚本

bash
#!/bin/bash
# 过滤错误日志脚本

# 配置
LOG_FILE="/var/log/syslog"
OUTPUT_FILE="/tmp/error.log"

# 过滤ERROR日志
echo "===== 过滤ERROR日志 ====="
grep "ERROR" "$LOG_FILE" > "$OUTPUT_FILE"

# 输出统计信息
ERROR_COUNT=$(wc -l < "$OUTPUT_FILE")
echo "ERROR日志数量:$ERROR_COUNT"
echo "ERROR日志已保存到:$OUTPUT_FILE"

# 显示前10行ERROR日志
echo "===== 前10行ERROR日志 ====="
head -n 10 "$OUTPUT_FILE"

使用方法

bash
# 赋予执行权限
chmod +x filter_error_log.sh

# 执行脚本
./filter_error_log.sh

3.2 过滤特定时间段的日志

过滤特定时间段的日志。

脚本

bash
#!/bin/bash
# 过滤特定时间段的日志脚本

# 配置
LOG_FILE="/var/log/syslog"
START_TIME="2024-01-01 00:00:00"
END_TIME="2024-01-01 23:59:59"
OUTPUT_FILE="/tmp/time_range.log"

# 过滤特定时间段的日志
echo "===== 过滤特定时间段的日志 ====="
echo "开始时间:$START_TIME"
echo "结束时间:$END_TIME"

# 转换时间格式
START_TIMESTAMP=$(date -d "$START_TIME" +%s)
END_TIMESTAMP=$(date -d "$END_TIME" +%s)

# 过滤日志
awk -v start="$START_TIMESTAMP" -v end="$END_TIMESTAMP" '{
    log_time = mktime(gensub(/[-:]/, " ", "g", $1 " " $2 " " $3 " " $4 " " $5))
    if (log_time >= start && log_time <= end) {
        print $0
    }
}' "$LOG_FILE" > "$OUTPUT_FILE"

# 输出统计信息
LOG_COUNT=$(wc -l < "$OUTPUT_FILE")
echo "日志数量:$LOG_COUNT"
echo "日志已保存到:$OUTPUT_FILE"

使用方法

bash
# 赋予执行权限
chmod +x filter_time_range_log.sh

# 执行脚本
./filter_time_range_log.sh

3.3 过滤特定IP的日志

过滤特定IP的日志。

脚本

bash
#!/bin/bash
# 过滤特定IP的日志脚本

# 配置
LOG_FILE="/var/log/syslog"
IP_ADDRESS="192.168.1.10"
OUTPUT_FILE="/tmp/ip.log"

# 过滤特定IP的日志
echo "===== 过滤特定IP的日志 ====="
echo "IP地址:$IP_ADDRESS"

# 过滤日志
grep "$IP_ADDRESS" "$LOG_FILE" > "$OUTPUT_FILE"

# 输出统计信息
LOG_COUNT=$(wc -l < "$OUTPUT_FILE")
echo "日志数量:$LOG_COUNT"
echo "日志已保存到:$OUTPUT_FILE"

# 显示前10行日志
echo "===== 前10行日志 ====="
head -n 10 "$OUTPUT_FILE"

使用方法

bash
# 赋予执行权限
chmod +x filter_ip_log.sh

# 执行脚本
./filter_ip_log.sh

4. 日志聚合脚本

4.1 按小时聚合日志

按小时聚合日志。

脚本

bash
#!/bin/bash
# 按小时聚合日志脚本

# 配置
LOG_FILE="/var/log/syslog"
OUTPUT_DIR="/tmp/hourly"

# 创建输出目录
mkdir -p "$OUTPUT_DIR"

# 按小时聚合日志
echo "===== 按小时聚合日志 ====="
awk '{print substr($1, 1, 13)}' "$LOG_FILE" | sort | uniq | while read hour
do
    # 创建小时日志文件
    HOUR_FILE="${OUTPUT_DIR}/${hour}.log"
    
    # 过滤该小时的日志
    grep "$hour" "$LOG_FILE" > "$HOUR_FILE"
    
    # 输出统计信息
    LOG_COUNT=$(wc -l < "$HOUR_FILE")
    echo "小时:$hour,日志数量:$LOG_COUNT,文件:$HOUR_FILE"
done

echo "日志聚合完成,输出目录:$OUTPUT_DIR"

使用方法

bash
# 赋予执行权限
chmod +x aggregate_hourly_log.sh

# 执行脚本
./aggregate_hourly_log.sh

4.2 按来源聚合日志

按来源聚合日志。

脚本

bash
#!/bin/bash
# 按来源聚合日志脚本

# 配置
LOG_FILE="/var/log/syslog"
OUTPUT_DIR="/tmp/source"

# 创建输出目录
mkdir -p "$OUTPUT_DIR"

# 按来源聚合日志
echo "===== 按来源聚合日志 ====="
awk '{print $5}' "$LOG_FILE" | sort | uniq | while read source
do
    # 创建来源日志文件
    SOURCE_FILE="${OUTPUT_DIR}/${source}.log"
    
    # 过滤该来源的日志
    grep "$source" "$LOG_FILE" > "$SOURCE_FILE"
    
    # 输出统计信息
    LOG_COUNT=$(wc -l < "$SOURCE_FILE")
    echo "来源:$source,日志数量:$LOG_COUNT,文件:$SOURCE_FILE"
done

echo "日志聚合完成,输出目录:$OUTPUT_DIR"

使用方法

bash
# 赋予执行权限
chmod +x aggregate_source_log.sh

# 执行脚本
./aggregate_source_log.sh

5. 日志分析脚本

5.1 分析错误日志

分析ERROR日志,找出错误的原因。

脚本

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

# 配置
LOG_FILE="/var/log/syslog"
OUTPUT_FILE="/tmp/error_analysis.log"

# 分析ERROR日志
echo "===== 分析ERROR日志 ====="

# 提取ERROR日志
grep "ERROR" "$LOG_FILE" > "$OUTPUT_FILE"

# 统计ERROR类型
echo "===== ERROR类型统计 ====="
awk '/ERROR/ {for (i=6; i<=NF; i++) printf "%s ", $i; print ""}' "$OUTPUT_FILE" | sort | uniq -c | sort -nr | head -20

# 统计ERROR来源
echo "===== ERROR来源统计 ====="
awk '/ERROR/ {print $5}' "$OUTPUT_FILE" | sort | uniq -c | sort -nr | head -20

# 统计ERROR时间分布
echo "===== ERROR时间分布 ====="
awk '/ERROR/ {print substr($1, 1, 10)}' "$OUTPUT_FILE" | sort | uniq -c | sort -nr

使用方法

bash
# 赋予执行权限
chmod +x analyze_error_log.sh

# 执行脚本
./analyze_error_log.sh

5.2 分析访问日志

分析Web服务器的访问日志。

脚本

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

# 配置
LOG_FILE="/var/log/nginx/access.log"

# 分析访问日志
echo "===== 分析访问日志 ====="

# 统计访问量
TOTAL_REQUESTS=$(wc -l < "$LOG_FILE")
echo "总访问量:$TOTAL_REQUESTS"

# 统计独立IP数
UNIQUE_IPS=$(awk '{print $1}' "$LOG_FILE" | sort | uniq | wc -l)
echo "独立IP数:$UNIQUE_IPS"

# 统计访问最多的IP
echo "===== 访问最多的IP(前10)====="
awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10

# 统计访问最多的URL
echo "===== 访问最多的URL(前10)====="
awk '{print $7}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10

# 统计HTTP状态码
echo "===== HTTP状态码统计 ====="
awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -nr

# 统计User-Agent
echo "===== User-Agent统计(前10)====="
awk -F'"' '{print $6}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -10

使用方法

bash
# 赋予执行权限
chmod +x analyze_access_log.sh

# 执行脚本
./analyze_access_log.sh

6. 日志监控脚本

6.1 实时监控日志

实时监控日志文件。

脚本

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

# 配置
LOG_FILE="/var/log/syslog"
KEYWORD="ERROR"

# 实时监控日志
echo "===== 实时监控日志 ====="
echo "日志文件:$LOG_FILE"
echo "关键词:$KEYWORD"
echo "按Ctrl+C退出"
echo ""

# 监控日志
tail -f "$LOG_FILE" | grep --line-buffered "$KEYWORD"

使用方法

bash
# 赋予执行权限
chmod +x monitor_log.sh

# 执行脚本
./monitor_log.sh

6.2 日志告警

当日志中出现特定关键词时发送告警。

脚本

bash
#!/bin/bash
# 日志告警脚本

# 配置
LOG_FILE="/var/log/syslog"
KEYWORD="ERROR"
EMAIL="admin@example.com"
INTERVAL=60

# 监控日志
echo "===== 日志告警 ====="
echo "日志文件:$LOG_FILE"
echo "关键词:$KEYWORD"
echo "告警间隔:${INTERVAL}秒"
echo ""

# 获取当前日志行数
LAST_LINE=$(wc -l < "$LOG_FILE")

# 监控日志
while true
do
    # 获取当前日志行数
    CURRENT_LINE=$(wc -l < "$LOG_FILE")
    
    # 检查是否有新日志
    if [ $CURRENT_LINE -gt $LAST_LINE ]; then
        # 提取新日志
        NEW_LOGS=$(tail -n +$((LAST_LINE + 1)) "$LOG_FILE")
        
        # 检查是否有关键词
        if echo "$NEW_LOGS" | grep -q "$KEYWORD"; then
            # 发送告警
            MESSAGE="发现$KEYWORD日志:\n$NEW_LOGS"
            echo -e "$MESSAGE" | mail -s "日志告警:$KEYWORD" "$EMAIL"
            echo "[$(date)] 发送告警:$KEYWORD"
        fi
        
        # 更新日志行数
        LAST_LINE=$CURRENT_LINE
    fi
    
    # 等待
    sleep $INTERVAL
done

使用方法

bash
# 赋予执行权限
chmod +x log_alert.sh

# 执行脚本
./log_alert.sh

7. 实战案例

案例1:综合日志分析系统

场景:实现一个综合日志分析系统,包括日志统计、日志过滤、日志聚合、日志分析。

脚本

bash
#!/bin/bash
# 综合日志分析系统

# 配置
LOG_FILE="/var/log/syslog"
OUTPUT_DIR="/tmp/log_analysis"
ANALYSIS_TYPE="$1"

# 创建输出目录
mkdir -p "$OUTPUT_DIR"

# 日志统计
function log_statistics {
    echo "===== 日志统计 ====="
    
    # 统计日志级别
    ERROR_COUNT=$(grep -c "ERROR" "$LOG_FILE")
    WARN_COUNT=$(grep -c "WARN" "$LOG_FILE")
    INFO_COUNT=$(grep -c "INFO" "$LOG_FILE")
    DEBUG_COUNT=$(grep -c "DEBUG" "$LOG_FILE")
    
    echo "ERROR数量:$ERROR_COUNT"
    echo "WARN数量:$WARN_COUNT"
    echo "INFO数量:$INFO_COUNT"
    echo "DEBUG数量:$DEBUG_COUNT"
    echo "总计:$((ERROR_COUNT + WARN_COUNT + INFO_COUNT + DEBUG_COUNT))"
}

# 日志过滤
function log_filter {
    echo "===== 日志过滤 ====="
    
    # 过滤ERROR日志
    ERROR_LOG="${OUTPUT_DIR}/error.log"
    grep "ERROR" "$LOG_FILE" > "$ERROR_LOG"
    echo "ERROR日志已保存到:$ERROR_LOG"
    
    # 过滤WARN日志
    WARN_LOG="${OUTPUT_DIR}/warn.log"
    grep "WARN" "$LOG_FILE" > "$WARN_LOG"
    echo "WARN日志已保存到:$WARN_LOG"
}

# 日志聚合
function log_aggregate {
    echo "===== 日志聚合 ====="
    
    # 按小时聚合日志
    HOURLY_DIR="${OUTPUT_DIR}/hourly"
    mkdir -p "$HOURLY_DIR"
    
    awk '{print substr($1, 1, 13)}' "$LOG_FILE" | sort | uniq | while read hour
    do
        HOUR_FILE="${HOURLY_DIR}/${hour}.log"
        grep "$hour" "$LOG_FILE" > "$HOUR_FILE"
        LOG_COUNT=$(wc -l < "$HOUR_FILE")
        echo "小时:$hour,日志数量:$LOG_COUNT"
    done
    
    echo "日志聚合完成,输出目录:$HOURLY_DIR"
}

# 日志分析
function log_analysis {
    echo "===== 日志分析 ====="
    
    # 分析ERROR日志
    ERROR_LOG="${OUTPUT_DIR}/error.log"
    grep "ERROR" "$LOG_FILE" > "$ERROR_LOG"
    
    # 统计ERROR类型
    echo "===== ERROR类型统计 ====="
    awk '/ERROR/ {for (i=6; i<=NF; i++) printf "%s ", $i; print ""}' "$ERROR_LOG" | sort | uniq -c | sort -nr | head -20
    
    # 统计ERROR来源
    echo "===== ERROR来源统计 ====="
    awk '/ERROR/ {print $5}' "$ERROR_LOG" | sort | uniq -c | sort -nr | head -20
}

# 根据分析类型执行分析
case "$ANALYSIS_TYPE" in
    statistics)
        log_statistics
        ;;
    filter)
        log_filter
        ;;
    aggregate)
        log_aggregate
        ;;
    analysis)
        log_analysis
        ;;
    all)
        log_statistics
        echo ""
        log_filter
        echo ""
        log_aggregate
        echo ""
        log_analysis
        ;;
    *)
        echo "使用方法:$0 {statistics|filter|aggregate|analysis|all}"
        exit 1
        ;;
esac

echo "日志分析完成"

使用方法

bash
# 赋予执行权限
chmod +x log_analysis_system.sh

# 执行日志统计
./log_analysis_system.sh statistics

# 执行日志过滤
./log_analysis_system.sh filter

# 执行日志聚合
./log_analysis_system.sh aggregate

# 执行日志分析
./log_analysis_system.sh analysis

# 执行所有分析
./log_analysis_system.sh all

课程总结

这节课我们学习了日志分析脚本实战。

核心内容:

  • 日志分析概述
  • 日志统计脚本(日志级别统计、日志频率统计、日志来源统计)
  • 日志过滤脚本(过滤错误日志、过滤特定时间段的日志、过滤特定IP的日志)
  • 日志聚合脚本(按小时聚合日志、按来源聚合日志)
  • 日志分析脚本(分析错误日志、分析访问日志)
  • 日志监控脚本(实时监控日志、日志告警)
  • 实战案例

重要命令:

  • grep:搜索文本
  • awk:文本处理
  • sort:排序文本
  • uniq:去重文本
  • wc:统计文本
  • tail:查看文件末尾
  • head:查看文件开头
  • mail:发送邮件

日志分析是运维工作的重要组成部分,掌握这些知识后,我们将在后续课程中学习系统监控脚本实战等内容。

课后练习

练习1(基础)

编写一个日志统计脚本,统计不同日志级别的数量。

练习2(进阶)

编写一个日志过滤脚本,过滤ERROR级别的日志。

练习3(拓展)

编写一个综合日志分析系统,包括日志统计、日志过滤、日志聚合、日志分析。

评论区

专业的Linux技术学习平台,从入门到精通的完整学习路径