本文目录导读:

我来提供一个实用的分类统计报错日志脚本,包含多种实现方案:
Python脚本(推荐,功能最完整)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
日志错误分类统计脚本
功能:读取日志文件,按错误类型进行分类统计
"""
import re
import os
from collections import defaultdict
from datetime import datetime
import argparse
class LogErrorAnalyzer:
def __init__(self, log_file):
self.log_file = log_file
self.error_stats = defaultdict(lambda: {
'count': 0,
'details': [],
'first_seen': None,
'last_seen': None,
'severity': 'ERROR'
})
def analyze(self):
"""分析日志文件"""
if not os.path.exists(self.log_file):
print(f"错误:文件 {self.log_file} 不存在")
return False
print(f"开始分析日志文件:{self.log_file}")
print(f"分析时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("-" * 60)
try:
with open(self.log_file, 'r', encoding='utf-8') as f:
for line_num, line in enumerate(f, 1):
self._process_line(line.strip(), line_num)
self._generate_report()
return True
except Exception as e:
print(f"读取文件错误:{e}")
return False
def _process_line(self, line, line_num):
"""处理每一行日志"""
if not line:
return
# 识别的错误模式
error_patterns = {
'CONNECTION_ERROR': [r'connection.*(?:refused|timeout|reset)',
r'connect.*failed'],
'AUTH_ERROR': [r'(?:login|auth|authenticate).*(?:fail|error|denied)',
r'invalid.*(?:password|token|credential)'],
'TIMEOUT_ERROR': [r'timeout', r'timed out'],
'DATABASE_ERROR': [r'(?:database|db|sql).*(?:error|fail|exception)',
r'query.*(?:failed|error)'],
'MEMORY_ERROR': [r'(?:memory|out of memory|oom)',
r'memory.*(?:overflow|limit)'],
'FILE_ERROR': [r'(?:file|io).*(?:not found|error|denied)',
r'permission.*denied'],
'NETWORK_ERROR': [r'(?:network|socket).*(?:error|fail)',
r'dns.*(?:error|fail)'],
'VALIDATION_ERROR': [r'(?:validation|invalid|illegal).*(?:argument|parameter|input)',
r'value.*(?:out of range|invalid)'],
'RUNTIME_ERROR': [r'(?:runtime|exception|error).*(?:occurred|raised)',
r'unexpected.*(?:error|exception)'],
}
# 通用错误匹配(如果没有更具体的分类)
is_error = False
for category, patterns in error_patterns.items():
for pattern in patterns:
if re.search(pattern, line, re.IGNORECASE):
self._record_error(category, line, line_num)
is_error = True
break
if is_error:
break
# 如果包含 ERROR 或 Exception 但没有匹配到具体分类
if not is_error and re.search(r'(?:ERROR|Exception|FATAL)', line, re.IGNORECASE):
self._record_error('OTHER_ERROR', line, line_num)
def _record_error(self, category, line, line_num):
"""记录错误信息"""
timestamp = self._extract_timestamp(line)
self.error_stats[category]['count'] += 1
# 记录详细信息和时间
detail = {
'line': line_num,
'message': line[:200], # 截取前200字符
'timestamp': timestamp or datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
if len(self.error_stats[category]['details']) < 100: # 最多保存100条详细记录
self.error_stats[category]['details'].append(detail)
if not self.error_stats[category]['first_seen'] or timestamp:
self.error_stats[category]['first_seen'] = detail['timestamp']
self.error_stats[category]['last_seen'] = detail['timestamp']
def _extract_timestamp(self, line):
"""尝试从日志行中提取时间戳"""
patterns = [
r'\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}',
r'\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2}',
r'\d{2}-\d{2}-\d{4} \d{2}:\d{2}:\d{2}',
]
for pattern in patterns:
match = re.search(pattern, line)
if match:
return match.group()
return None
def _generate_report(self):
"""生成统计报告"""
if not self.error_stats:
print("未发现任何错误日志")
return
total_errors = sum(v['count'] for v in self.error_stats.values())
print(f"\n{'='*60}")
print(f"错误分类统计报告")
print(f"{'='*60}")
print(f"总错误数:{total_errors}")
print(f"错误类型数:{len(self.error_stats)}")
print(f"{'='*60}")
# 按错误数量降序排列
sorted_errors = sorted(self.error_stats.items(),
key=lambda x: x[1]['count'], reverse=True)
for category, stats in sorted_errors:
percentage = (stats['count'] / total_errors) * 100
print(f"\n📊 {self._format_category(category)}")
print(f" 数量:{stats['count']} ({percentage:.2f}%)")
print(f" 首次时间:{stats['first_seen'] or 'N/A'}")
print(f" 最后时间:{stats['last_seen'] or 'N/A'}")
# 显示前5条详细记录
if stats['details']:
print(f" 最近错误示例(最多显示5条):")
for detail in stats['details'][-5:]:
print(f" • 第{detail['line']}行: {detail['message'][:100]}")
def _format_category(self, category):
"""格式化错误类别名称"""
names = {
'CONNECTION_ERROR': '连接错误',
'AUTH_ERROR': '认证错误',
'TIMEOUT_ERROR': '超时错误',
'DATABASE_ERROR': '数据库错误',
'MEMORY_ERROR': '内存错误',
'FILE_ERROR': '文件错误',
'NETWORK_ERROR': '网络错误',
'VALIDATION_ERROR': '验证错误',
'RUNTIME_ERROR': '运行时错误',
'OTHER_ERROR': '其他错误'
}
return f"{names.get(category, category)} ({category})"
def main():
parser = argparse.ArgumentParser(description='日志错误分类统计工具')
parser.add_argument('log_file', help='要分析的日志文件路径')
parser.add_argument('--output', '-o', help='输出报告到文件(可选)')
args = parser.parse_args()
analyzer = LogErrorAnalyzer(args.log_file)
analyzer.analyze()
if args.output and hasattr(analyzer, 'error_stats'):
with open(args.output, 'w', encoding='utf-8') as f:
f.write("错误统计报告\n")
f.write(f"文件: {args.log_file}\n")
f.write(f"时间: {datetime.now()}\n\n")
for category, stats in analyzer.error_stats.items():
f.write(f"{category}: {stats['count']}次\n")
if __name__ == "__main__":
main()
Shell脚本(轻量级,适合Linux环境)
#!/bin/bash
# 日志错误分类统计脚本
# 使用方法: ./error_stats.sh [日志文件路径]
LOG_FILE="${1:-/var/log/syslog}"
if [ ! -f "$LOG_FILE" ]; then
echo "错误:文件 $LOG_FILE 不存在"
exit 1
fi
echo "=============================="
echo "日志错误分类统计"
echo "文件: $LOG_FILE"
echo "时间: $(date)"
echo "=============================="
# 定义错误类别和对应的grep模式
declare -A ERROR_CATEGORIES
ERROR_CATEGORIES=(
["连接错误"]="connection refused|connection timeout|connection reset"
["认证错误"]="authentication failed|login failed|permission denied"
["超时错误"]="timeout|timed out"
["数据库错误"]="database error|SQL error|query failed"
["内存错误"]="out of memory|memory error|OOM"
["文件错误"]="file not found|IO error|open failed"
["网络错误"]="network error|socket error|connection failed"
["系统错误"]="kernel error|fatal error|segfault"
["其他错误"]="ERROR|FATAL|Exception"
)
# 统计所有错误
total_errors=0
for category in "${!ERROR_CATEGORIES[@]}"; do
pattern="${ERROR_CATEGORIES[$category]}"
count=$(grep -icE "$pattern" "$LOG_FILE" 2>/dev/null)
if [ "$count" -gt 0 ]; then
total_errors=$((total_errors + count))
echo ""
echo "📊 $category"
echo " 数量: $count"
# 显示最近的错误示例(最多3条)
if [ "$count" -le 3 ]; then
echo " 错误示例:"
grep -iE "$pattern" "$LOG_FILE" | head -3 | while IFS= read -r line; do
echo " • ${line:0:100}"
done
else
echo " 最近错误示例:"
grep -iE "$pattern" "$LOG_FILE" | tail -3 | while IFS= read -r line; do
echo " • ${line:0:100}"
done
fi
fi
done
echo ""
echo "=============================="
echo "统计总计"
echo "总错误数: $total_errors"
echo "=============================="
使用awk的快速统计脚本
#!/bin/bash
# 使用awk快速统计错误类型
log_file="${1:-/var/log/syslog}"
if [ ! -f "$log_file" ]; then
echo "文件不存在: $log_file"
exit 1
fi
awk '
BEGIN {
print "错误类型统计报告"
print "================\n"
}
{
# 初始化错误计数
if ($0 ~ /[Ee]rror/) total_errors++
# 分类统计
if ($0 ~ /connection.*refused|connection.*timeout/) connection_error++
if ($0 ~ /login.*failed|auth.*fail/) auth_error++
if ($0 ~ /[Tt]imeout/) timeout_error++
if ($0 ~ /database.*error|SQL.*error/) database_error++
if ($0 ~ /out of memory|memory.*error/) memory_error++
if ($0 ~ /file not found|IO error/) file_error++
if ($0 ~ /network.*error|socket.*error/) network_error++
}
END {
printf "总错误行数: %d\n\n", total_errors
printf "连接错误: %d\n", connection_error + 0
printf "认证错误: %d\n", auth_error + 0
printf "超时错误: %d\n", timeout_error + 0
printf "数据库错误: %d\n", database_error + 0
printf "内存错误: %d\n", memory_error + 0
printf "文件错误: %d\n", file_error + 0
printf "网络错误: %d\n", network_error + 0
print "\n========= 统计完成 ========="
}' "$log_file"
使用示例
# Python版本 python3 log_error_analyzer.py /var/log/app.log python3 log_error_analyzer.py /var/log/app.log --output report.txt # Shell版本 chmod +x error_stats.sh ./error_stats.sh /var/log/syslog # awk版本 ./error_analysis.awk /var/log/application.log
高级功能扩展
如果你需要更强大的功能,可以考虑:
- 实时监控:使用
tail -f实时分析日志 - 邮件告警:当某类错误超过阈值时发送通知
- 趋势分析:按时间段统计错误趋势
- JSON输出:方便集成到监控系统
- 多文件分析:同时分析多个日志文件
这个脚本可以根据你的具体需求进行调整,比如修改错误模式匹配规则、添加更多错误类别等。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播