日志解析需求:提取指定字段并输出为CSV文件
解析日志并导出为CSV文件的解决方案
先帮你梳理清楚日志里的核心信息,然后用Python写一个实用的脚本完成解析和导出,灵活又好调整。
步骤1:确定要提取的字段
从你给出的日志示例里,我们可以提取这些关键字段:
- Timestamp:日志记录的完整时间(比如
2018-02-19 15:55:50.070) - LogLevel:日志级别(比如
INFO) - Username:执行上传操作的用户名(比如
zzz) - UserID:对应用户的ID(比如
708473232) - HDFSPath:上传的HDFS文件完整路径
- ChunkCount:文件拆分的分块数量(比如
4) - TotalOps:总操作次数(比如
31) - FailedOps:失败的操作次数(比如
0)
步骤2:Python脚本实现解析与导出
下面是完整的脚本,用正则表达式匹配日志格式,提取字段后直接写入CSV文件:
import re import csv # 定义匹配日志的正则规则,完美适配你的日志格式 log_regex = re.compile( r'^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}) ' r't\.a\.ApiUploader \[(\w+)\] ' r'(\w+)\((\d+)\) uploaded file \'([^\']+)\' ' r'(?:in (\d+) chunk\(s\) - total ops: (\d+), failed ops: (\d+))?' ) # 这里可以替换成读取本地日志文件的逻辑,比如: # with open('your_log_file.log', 'r', encoding='utf-8') as f: # log_lines = f.readlines() log_lines = [ "2018-02-19 15:55:50.070 t.a.ApiUploader [INFO] zzz(708473232) uploaded file 'hdfs://fr-de.int.fz.net:4010/user/profile_export/aId=6/empId=4/classId=10/members-x--491eedd6-2e14-488f-8c13-84be2c6f777b.txt.gz' in 4 chunk(s) - total ops: 31, failed ops: 0", "2018-02-19 15:55:50.092 t.a.ApiUploader [INFO] zzz(617022301) uploaded file 'hdfs://fr-de.int.fz.net:4010/user/profile_export/aId=6/empId=4/classId=10/members-x-de10af80-4ac5-4b..." ] # 生成CSV文件 output_columns = ['Timestamp', 'LogLevel', 'Username', 'UserID', 'HDFSPath', 'ChunkCount', 'TotalOps', 'FailedOps'] with open('upload_logs.csv', 'w', newline='', encoding='utf-8') as csv_file: writer = csv.DictWriter(csv_file, fieldnames=output_columns) writer.writeheader() for line in log_lines: match_result = log_regex.match(line.strip()) if match_result: timestamp, log_level, username, user_id, hdfs_path, chunk_count, total_ops, failed_ops = match_result.groups() # 处理截断的日志行(比如第二行缺失分块、操作数信息) result_row = { 'Timestamp': timestamp, 'LogLevel': log_level, 'Username': username, 'UserID': user_id, 'HDFSPath': hdfs_path.rstrip('...'), # 去掉路径末尾的省略号 'ChunkCount': chunk_count or 'N/A', 'TotalOps': total_ops or 'N/A', 'FailedOps': failed_ops or 'N/A' } writer.writerow(result_row) print("解析完成,已生成CSV文件:upload_logs.csv")
脚本细节说明
- 正则适配:正则里的
?标记了分块、操作数部分为可选,完美兼容完整日志和截断日志。 - 日志读取:如果你的日志是本地文件,直接替换
log_lines的赋值逻辑即可,支持大文件逐行读取(避免内存占用过高)。 - 异常处理:对于截断的日志,缺失的字段会自动填充为
N/A,路径末尾的...也会被清理。 - CSV兼容性:生成的CSV带表头,直接可以用Excel、Tableau等工具打开分析。
扩展小技巧
- 如果日志格式有微调,只需要修改正则表达式里对应的匹配片段就行。
- 要是需要处理百万级别的日志,可以改用
csv.writer逐行写入,进一步优化性能。
内容的提问来源于stack exchange,提问作者user175084




