日志统计与分析指南

日志统计与分析指南

目录


1. 多文件查找

1.1 查找普通日志文件(.log)

# 查找当前目录及子目录下所有 .log 文件
find . -name "*.log"

# 查找指定目录下的 .log 文件
find /var/log -name "*.log"

# 查找最近修改的日志文件
find . -name "*.log" -mtime -1  # 最近1天
find . -name "*.log" -mtime -7  # 最近7天

1.2 查找压缩日志文件

# 查找 .gz 压缩文件
find . -name "*.log.gz"
find . -name "*.gz"

# 查找 .zip 压缩文件
find . -name "*.log.zip"
find . -name "*.zip"

# 查找多种压缩格式
find . \( -name "*.log.gz" -o -name "*.log.zip" -o -name "*.log.bz2" \)

# 查找所有压缩文件(包括 .gz, .zip, .bz2, .xz)
find . -type f \( -name "*.gz" -o -name "*.zip" -o -name "*.bz2" -o -name "*.xz" \)

1.3 同时查找普通和压缩日志文件

# 方法1:使用 -o 选项
find . \( -name "*.log" -o -name "*.log.gz" -o -name "*.log.zip" \)

# 方法2:使用正则表达式(需要 -regex 选项)
find . -regex ".*\.log\(\.gz\|\.zip\)\?$"

# 方法3:分别查找后合并
find . -name "*.log" -o -name "*.log.*" | grep -E "\.(log|gz|zip|bz2)$"

1.4 按时间范围查找日志文件

# 查找今天修改的文件
find . -name "*.log*" -mtime 0

# 查找最近3天的文件
find . -name "*.log*" -mtime -3

# 查找指定日期范围的文件(需要结合 stat 或 ls)
find . -name "*.log*" -newermt "2025-01-01" ! -newermt "2025-01-31"

2. 查找日志的常用方法

2.1 grep - 最常用的文本搜索工具

grep 常用选项表格
选项说明示例
-i忽略大小写grep -i "error" app.log
-n显示匹配行的行号grep -n "ERROR" app.log
-v反向匹配,显示不包含关键字的行grep -v "INFO" app.log
-c统计匹配的行数grep -c "ERROR" app.log
-l只显示匹配的文件名grep -l "ERROR" *.log
-L只显示不匹配的文件名grep -L "ERROR" *.log
-r-R递归搜索目录grep -r "ERROR" /var/log/
-E使用扩展正则表达式grep -E "ERROR|WARN" app.log
-F将模式视为固定字符串(不使用正则)grep -F "ERROR" app.log
-A n显示匹配行及其后 n 行grep -A 3 "ERROR" app.log
-B n显示匹配行及其前 n 行grep -B 3 "ERROR" app.log
-C n显示匹配行及其前后各 n 行grep -C 3 "ERROR" app.log
-o只显示匹配的部分,而不是整行grep -o "ERROR" app.log
-h不显示文件名前缀(多文件搜索时)grep -h "ERROR" *.log
-H显示文件名前缀(默认行为)grep -H "ERROR" app.log
-w匹配整个单词grep -w "error" app.log
-x匹配整行grep -x "ERROR" app.log
-q静默模式,不输出结果(用于脚本判断)grep -q "ERROR" app.log && echo "Found"
-s抑制错误消息grep -s "ERROR" app.log
--color高亮显示匹配的文本grep --color=always "ERROR" app.log
-m n最多匹配 n 行后停止grep -m 10 "ERROR" app.log
-f file从文件中读取模式grep -f patterns.txt app.log
-e pattern指定多个模式grep -e "ERROR" -e "WARN" app.log
使用示例
# 基本搜索
grep "ERROR" app.log

# 忽略大小写
grep -i "error" app.log

# 显示行号
grep -n "ERROR" app.log

# 显示匹配行的上下文(前后各3行)
grep -C 3 "ERROR" app.log
grep -B 3 "ERROR" app.log  # 只显示前3行
grep -A 3 "ERROR" app.log  # 只显示后3行

# 反向匹配(显示不包含关键字的行)
grep -v "INFO" app.log

# 使用正则表达式
grep -E "ERROR|WARN" app.log
grep -E "[0-9]{4}-[0-9]{2}-[0-9]{2}" app.log  # 匹配日期格式

# 在多个文件中搜索
grep "ERROR" *.log
grep -r "ERROR" /var/log/  # 递归搜索目录

# 只显示匹配的文件名
grep -l "ERROR" *.log

# 统计匹配的行数
grep -c "ERROR" app.log

# 只显示匹配的部分
grep -o "ERROR" app.log | wc -l  # 统计关键字出现次数

# 匹配整个单词
grep -w "error" app.log  # 不会匹配 "errors" 或 "ErrorCode"

# 高亮显示匹配文本
grep --color=always "ERROR" app.log

# 组合使用多个选项
grep -rn --color=always "ERROR" /var/log/  # 递归搜索、显示行号、高亮显示

2.2 在压缩文件中搜索

# 在 .gz 文件中搜索(zcat 或 zgrep)
zgrep "ERROR" app.log.gz
zcat app.log.gz | grep "ERROR"

# 在 .bz2 文件中搜索
bzgrep "ERROR" app.log.bz2
bzcat app.log.bz2 | grep "ERROR"

# 在 .xz 文件中搜索
xzgrep "ERROR" app.log.xz
xzcat app.log.xz | grep "ERROR"

# 在 .zip 文件中搜索
unzip -p app.log.zip | grep "ERROR"

# 在多个压缩文件中搜索
zgrep "ERROR" *.log.gz

2.3 多文件同时搜索

# 在多个普通日志文件中搜索
grep "ERROR" app.log app2.log app3.log

# 在普通文件和压缩文件中同时搜索
grep "ERROR" *.log && zgrep "ERROR" *.log.gz

# 使用 find + xargs 在多个文件中搜索
find . -name "*.log*" -type f | xargs grep "ERROR"

# 处理包含空格的文件名
find . -name "*.log*" -type f -print0 | xargs -0 grep "ERROR"

2.4 按时间范围搜索

# 搜索指定时间段的日志(假设日志格式包含时间戳)
grep "2025-01-15" app.log | grep "ERROR"

# 搜索时间范围(需要日志格式支持)
awk '/2025-01-15 10:00:00/,/2025-01-15 11:00:00/' app.log

# 使用 sed 提取时间范围
sed -n '/2025-01-15 10:00:00/,/2025-01-15 11:00:00/p' app.log

2.5 高级搜索技巧

# 组合多个条件(AND)
grep "ERROR" app.log | grep "PmsService"

# 组合多个条件(OR)
grep -E "ERROR|WARN|FATAL" app.log

# 排除某些行
grep "ERROR" app.log | grep -v "DEBUG"

# 使用管道链
cat app.log | grep "ERROR" | grep "PmsService" | head -20

# 实时监控日志(tail + grep)
tail -f app.log | grep "ERROR"

3. 统计日志内容

3.1 统计行数

# 统计文件总行数
wc -l app.log

# 统计多个文件的行数
wc -l *.log

# 统计匹配关键字的行数
grep -c "ERROR" app.log

# 统计多个文件中匹配的行数
grep -c "ERROR" *.log

# 统计压缩文件的行数
zcat app.log.gz | wc -l

3.2 统计关键字出现次数

# 统计单个关键字出现次数
grep -o "ERROR" app.log | wc -l

# 统计多个关键字出现次数
grep -oE "ERROR|WARN|FATAL" app.log | sort | uniq -c

# 统计每个关键字的出现次数并排序
grep -oE "ERROR|WARN|FATAL" app.log | sort | uniq -c | sort -rn

# 统计所有唯一关键字的出现次数
grep -oE "ERROR|WARN|FATAL" app.log | sort | uniq -c

3.3 统计关键字频率(Top N)

# 统计出现频率最高的10个关键字
grep -oE "ERROR|WARN|FATAL" app.log | sort | uniq -c | sort -rn | head -10

# 统计所有单词的频率(Top 20)
cat app.log | tr -s ' ' '\n' | sort | uniq -c | sort -rn | head -20

# 统计特定模式的频率(如类名、方法名)
grep -oE "\[PmsService\]|\[CouponService\]" app.log | sort | uniq -c | sort -rn

3.4 按时间统计

# 统计每小时错误数量(假设日志格式:yyyy-MM-dd HH:mm:ss)
grep "ERROR" app.log | awk '{print $1" "$2}' | cut -d: -f1 | sort | uniq -c

# 统计每天的日志行数
awk '{print $1}' app.log | sort | uniq -c

# 统计每分钟的请求数(需要根据实际日志格式调整)
awk '{print substr($0,1,16)}' app.log | sort | uniq -c

3.5 统计文件大小

# 查看文件大小
ls -lh app.log

# 查看多个文件的总大小
du -ch *.log

# 查看压缩文件大小
ls -lh *.log.gz

# 查看目录下所有日志文件的总大小
du -sh /var/log/

3.6 统计唯一值

# 统计唯一的错误类型
grep "ERROR" app.log | awk -F'ERROR' '{print $2}' | sort | uniq

# 统计唯一的用户ID(假设日志中包含用户ID)
grep -oE "userId:[0-9]+" app.log | sort | uniq

# 统计唯一的IP地址
grep -oE "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" app.log | sort | uniq

4. 高级功能

4.1 日志聚合分析

# 合并多个日志文件并排序
cat *.log | sort

# 合并并去重
cat *.log | sort | uniq

# 合并压缩文件
zcat *.log.gz | sort

4.2 提取特定字段

# 使用 awk 提取特定列
awk '{print $1, $2, $5}' app.log  # 提取第1、2、5列

# 提取 JSON 格式日志中的特定字段(需要 jq)
cat app.log | jq '.level, .message'

# 提取时间戳和错误信息
grep "ERROR" app.log | awk '{print $1" "$2" "$NF}'

4.3 日志格式化输出

# 美化 JSON 日志(需要 jq)
cat app.log | jq '.'

# 格式化时间戳
awk '{print strftime("%Y-%m-%d %H:%M:%S", $1)}' app.log

# 添加行号
cat -n app.log

4.4 日志对比分析

# 对比两个日志文件的差异
diff app.log app2.log

# 对比并显示上下文
diff -u app.log app2.log

# 找出只在文件1中存在的行
comm -23 <(sort app.log) <(sort app2.log)

# 找出两个文件共有的行
comm -12 <(sort app.log) <(sort app2.log)

4.5 性能分析

# 统计接口响应时间(假设日志包含耗时信息)
grep -oE "耗时 [0-9]+ ms" app.log | grep -oE "[0-9]+" | awk '{sum+=$1; count++} END {print "平均耗时:", sum/count, "ms"}'

# 找出最慢的10个请求
grep -oE "耗时 [0-9]+ ms" app.log | grep -oE "[0-9]+" | sort -rn | head -10

# 统计耗时分布
grep -oE "耗时 [0-9]+ ms" app.log | grep -oE "[0-9]+" | awk '{if($1<100) a++; else if($1<500) b++; else c++} END {print "0-100ms:", a, "100-500ms:", b, ">500ms:", c}'

4.6 错误分析

# 提取错误堆栈
awk '/ERROR/,/^[[:space:]]*$/' app.log

# 统计异常类型
grep -oE "Exception: [a-zA-Z.]+" app.log | sort | uniq -c | sort -rn

# 找出最常见的错误消息
grep "ERROR" app.log | awk -F'ERROR' '{print $2}' | sort | uniq -c | sort -rn | head -10

4.7 实时监控

# 实时监控日志文件
tail -f app.log

# 实时监控并过滤
tail -f app.log | grep "ERROR"

# 监控多个日志文件
tail -f app.log app2.log

# 实时监控并高亮关键字
tail -f app.log | grep --color=always -E "ERROR|WARN|FATAL"

4.8 日志采样

# 每10行采样1行
awk 'NR % 10 == 0' app.log

# 随机采样1000行
shuf -n 1000 app.log

# 采样前1000行和后1000行
head -1000 app.log && tail -1000 app.log

5. 实用脚本示例

5.1 统计所有日志文件中的错误数量

#!/bin/bash
# 统计所有日志文件(包括压缩文件)中的错误数量

LOG_DIR="/var/log"
KEYWORD="ERROR"

echo "正在统计 $LOG_DIR 目录下的错误日志..."

# 统计普通日志文件
for file in $(find $LOG_DIR -name "*.log" -type f); do
    count=$(grep -c "$KEYWORD" "$file" 2>/dev/null || echo "0")
    echo "$file: $count"
done

# 统计压缩日志文件
for file in $(find $LOG_DIR -name "*.log.gz" -type f); do
    count=$(zgrep -c "$KEYWORD" "$file" 2>/dev/null || echo "0")
    echo "$file: $count"
done

5.2 按日期统计日志

#!/bin/bash
# 按日期统计日志行数

LOG_FILE="app.log"

echo "日期统计:"
awk '{print $1}' $LOG_FILE | sort | uniq -c | sort -rn

5.3 提取错误日志到单独文件

#!/bin/bash
# 从多个日志文件中提取错误日志

OUTPUT_FILE="errors.log"
KEYWORD="ERROR"

> $OUTPUT_FILE  # 清空输出文件

# 处理普通日志文件
for file in *.log; do
    if [ -f "$file" ]; then
        echo "处理文件: $file"
        grep "$KEYWORD" "$file" >> $OUTPUT_FILE
    fi
done

# 处理压缩日志文件
for file in *.log.gz; do
    if [ -f "$file" ]; then
        echo "处理文件: $file"
        zgrep "$KEYWORD" "$file" >> $OUTPUT_FILE
    fi
done

echo "错误日志已保存到: $OUTPUT_FILE"

5.4 分析日志中的慢请求

#!/bin/bash
# 分析日志中的慢请求(假设日志包含耗时信息)

LOG_FILE="app.log"
THRESHOLD=1000  # 阈值:1000ms

echo "查找耗时超过 ${THRESHOLD}ms 的请求:"
grep -E "耗时 [0-9]+ ms" $LOG_FILE | \
    grep -oE "耗时 [0-9]+ ms" | \
    grep -oE "[0-9]+" | \
    awk -v threshold=$THRESHOLD '$1 > threshold {print $1" ms"}' | \
    sort -rn | head -20

5.5 统计日志文件大小和行数

#!/bin/bash
# 统计所有日志文件的大小和行数

echo "文件大小 | 行数 | 文件名"
echo "----------------------------------------"

for file in $(find . -name "*.log*" -type f); do
    if [[ $file == *.gz ]]; then
        size=$(du -h "$file" | cut -f1)
        lines=$(zcat "$file" 2>/dev/null | wc -l)
    elif [[ $file == *.bz2 ]]; then
        size=$(du -h "$file" | cut -f1)
        lines=$(bzcat "$file" 2>/dev/null | wc -l)
    else
        size=$(du -h "$file" | cut -f1)
        lines=$(wc -l < "$file")
    fi
    printf "%-10s | %-8s | %s\n" "$size" "$lines" "$file"
done

5.6 一键日志分析报告

#!/bin/bash
# 生成日志分析报告

LOG_FILE="${1:-app.log}"
REPORT_FILE="log_report_$(date +%Y%m%d_%H%M%S).txt"

{
    echo "========================================="
    echo "日志分析报告"
    echo "生成时间: $(date)"
    echo "日志文件: $LOG_FILE"
    echo "========================================="
    echo ""
    
    echo "1. 基本信息"
    echo "----------------------------------------"
    echo "总行数: $(wc -l < $LOG_FILE)"
    echo "文件大小: $(du -h $LOG_FILE | cut -f1)"
    echo ""
    
    echo "2. 错误统计"
    echo "----------------------------------------"
    echo "ERROR 数量: $(grep -c "ERROR" $LOG_FILE 2>/dev/null || echo "0")"
    echo "WARN 数量: $(grep -c "WARN" $LOG_FILE 2>/dev/null || echo "0")"
    echo "FATAL 数量: $(grep -c "FATAL" $LOG_FILE 2>/dev/null || echo "0")"
    echo ""
    
    echo "3. Top 10 错误消息"
    echo "----------------------------------------"
    grep "ERROR" $LOG_FILE | awk -F'ERROR' '{print $2}' | sort | uniq -c | sort -rn | head -10
    echo ""
    
    echo "4. 时间分布(按小时)"
    echo "----------------------------------------"
    awk '{print $2}' $LOG_FILE | cut -d: -f1 | sort | uniq -c
    echo ""
    
} > $REPORT_FILE

echo "报告已生成: $REPORT_FILE"
cat $REPORT_FILE

5.7 使用说明

# 给脚本添加执行权限
chmod +x script_name.sh

# 运行脚本
./script_name.sh

# 或者直接使用 bash 运行
bash script_name.sh

6. 常用工具推荐

6.1 命令行工具

  • grep: 文本搜索(已内置)
  • awk: 文本处理(已内置)
  • sed: 流编辑器(已内置)
  • jq: JSON 处理工具(需要安装)
  • rg (ripgrep): 更快的 grep 替代品(需要安装)
  • ag (The Silver Searcher): 代码搜索工具(需要安装)

6.2 安装额外工具

# macOS
brew install jq ripgrep the_silver_searcher

# Ubuntu/Debian
sudo apt-get install jq ripgrep silversearcher-ag

# CentOS/RHEL
sudo yum install jq epel-release
sudo yum install ripgrep the_silver_searcher

6.3 使用 ripgrep (rg) 的优势

# rg 比 grep 更快,且默认递归搜索
rg "ERROR" .                    # 递归搜索当前目录
rg "ERROR" --type log           # 只搜索日志文件
rg "ERROR" -g "*.log"           # 使用 glob 模式
rg "ERROR" -g "*.log.gz"        # 搜索压缩文件(需要配合其他工具)

7. 最佳实践

7.1 日志文件管理

  • 定期清理旧日志文件
  • 使用日志轮转(logrotate)
  • 压缩历史日志以节省空间
  • 设置日志保留策略

7.2 搜索优化

  • 使用 grep -E 进行正则匹配时,尽量使用具体模式
  • 大文件搜索时,先使用 headtail 缩小范围
  • 压缩文件搜索时,优先使用 zgrep 等专用工具

7.3 性能考虑

  • 大文件处理时,考虑使用 split 分割文件
  • 使用 parallel 工具并行处理多个文件
  • 对于超大数据集,考虑使用专门的日志分析工具(如 ELK Stack)

8. 快速参考

8.1 常用命令速查

需求命令
查找所有日志文件find . -name "*.log*"
搜索关键字grep "ERROR" app.log
统计行数wc -l app.log
统计关键字数量grep -c "ERROR" app.log
实时监控tail -f app.log | grep "ERROR"
搜索压缩文件zgrep "ERROR" app.log.gz
提取时间范围sed -n '/start/,/end/p' app.log
统计频率grep -o "ERROR" app.log | sort | uniq -c

8.2 常用组合命令

# 查找 + 搜索 + 统计
find . -name "*.log" -exec grep -c "ERROR" {} \;

# 搜索 + 排序 + 去重 + 统计
grep "ERROR" app.log | sort | uniq -c | sort -rn

# 提取 + 格式化 + 输出
grep "ERROR" app.log | awk '{print $1, $2, $NF}' > errors.txt

提示: 根据实际日志格式调整命令中的字段分隔符和模式匹配规则。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值