日志统计与分析指南 目录 1. 多文件查找 2. 查找日志的常用方法 3. 统计日志内容 4. 高级功能 5. 实用脚本示例 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*" -mtime0 # 查找最近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 -C3 "ERROR" app.loggrep -B3 "ERROR" app.log# 只显示前3行 grep -A3 "ERROR" app.log# 只显示后3行 # 反向匹配(显示不包含关键字的行) grep -v"INFO" app.log# 使用正则表达式 grep -E"ERROR|WARN" app.loggrep -E"[0-9]{4}-[0-9]{2}-[0-9]{2}" app.log# 匹配日期格式 # 在多个文件中搜索 grep "ERROR" *.loggrep -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.gz2.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 -0grep "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.log2.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 -l3.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 -c3.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 -rn3.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 -c3.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.log4.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 -104.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 -n1000 app.log# 采样前1000行和后1000行 head -1000 app.log&& tail -1000 app.log5. 实用脚本示例 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 -rn5.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 -vthreshold = $THRESHOLD '$1 > threshold {print$1 " ms"}' | \ sort -rn| head -205.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_FILE2 > /dev/null|| echo "0" ) " echo "WARN 数量:$( grep -c"WARN" $LOG_FILE2 > /dev/null|| echo "0" ) " echo "FATAL 数量:$( grep -c"FATAL" $LOG_FILE2 > /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 -10echo "" echo "4. 时间分布(按小时)" echo "----------------------------------------" awk '{print$2 }' $LOG_FILE | cut -d: -f1| sort | uniq -cecho "" } > $REPORT_FILE echo "报告已生成:$REPORT_FILE " cat $REPORT_FILE 5.7 使用说明 # 给脚本添加执行权限 chmod +x script_name.sh# 运行脚本 ./script_name.sh# 或者直接使用 bash 运行 bash script_name.sh6. 常用工具推荐 6.1 命令行工具 grep : 文本搜索(已内置)awk : 文本处理(已内置)sed : 流编辑器(已内置)jq : JSON 处理工具(需要安装)rg (ripgrep) : 更快的 grep 替代品(需要安装)ag (The Silver Searcher) : 代码搜索工具(需要安装)6.2 安装额外工具 # macOS brewinstall jq ripgrep the_silver_searcher# Ubuntu/Debian sudo apt-get install jq ripgrep silversearcher-ag# CentOS/RHEL sudo yuminstall jq epel-releasesudo yuminstall ripgrep the_silver_searcher6.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进行正则匹配时,尽量使用具体模式 大文件搜索时,先使用head或tail缩小范围 压缩文件搜索时,优先使用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" -execgrep -c"ERROR" { } \ ; # 搜索 + 排序 + 去重 + 统计 grep "ERROR" app.log| sort | uniq -c| sort -rn# 提取 + 格式化 + 输出 grep "ERROR" app.log| awk '{print$1 ,$2 ,$NF }' > errors.txt提示 : 根据实际日志格式调整命令中的字段分隔符和模式匹配规则。