遇到的问题
需要定期迁移同步多张表的数据,使用datax执行定制任务,但是每天都需要去查看数据同步的数据量,及其执行是否成功,但是datax原生的日志文档查看,需要一张一张的打开阅读,所以就有了想批量汇总的想法
梳理日志文档特征
查看日志后发现,执行成功的日志,过程参数会在日志结尾记录并且具有标准格式,格式如下:
任务启动时刻 : 2021-10-13 11:22:33
任务结束时刻 : 2021-10-13 11:26:39
任务总计耗时 : 246s
任务平均流量 : 1.28KB/s
记录写入速度 : 5rec/s
读出记录总数 : 134239
读写失败总数 : 0
而执行失败的,就显得五花八门了,所以只能通过识别正确执行的特征,剩余的都做标记,人工排查。
格式特征一致,所以采用 正则表达式的方式判断:
任务结束时刻\s+:\s+(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}).*?
任务总计耗时\s+:\s+(\d+)s\s+
任务平均流量\s+:\s+(\S+)\s+
记录写入速度\s+:\s+(\S+)\s+
读出记录总数\s+:\s+(\d+)\s+
读写失败总数\s+:\s+(\d+)
接下来就是,对指定日志文档中,所有以.log尾缀的文件,进行遍历,截取文档的最后7行,然后判断格式,满足格式,提取参数,不满足则认定为执行报错,具体代码如下:
import os
import csv
import re
from datetime import datetime
# 获取文件夹中所有的 .log 文件
folder_path = r"E:\Datax\datax\log\2021-10-13"
log_files = [f for f in os.listdir(folder_path) if f.endswith(".log")]
# 创建一个空的表格
table_data = []
log_end_pattern = re.compile(
r"任务结束时刻\s+:\s+(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}).*?任务总计耗时\s+:\s+(\d+)s\s+任务平均流量\s+:\s+(\S+)\s+记录写入速度\s+:\s+(\S+)\s+读出记录总数\s+:\s+(\d+)\s+读写失败总数\s+:\s+(\d+)",
re.DOTALL
)
# 遍历所有 .log 文件
for log_file in log_files:
file_path = os.path.join(folder_path, log_file)
# 读取文件的最后8行
with open(file_path, "r", encoding="utf-8") as file:
last_lines = file.readlines()[-8:] # 读取最后8行
# 合并最后8行为一个字符串,作为模拟的日志数据
log_content = "".join(last_lines)
# 检查文件结尾是否符合格式
match = log_end_pattern.search(log_content)
if match:
# 提取信息
end_time_str, total_time, avg_flow, write_speed, read_count, write_failures = match.groups()
# 将字符串转换为 datetime 对象
end_time = datetime.strptime(end_time_str, "%Y-%m-%d %H:%M:%S")
# 添加信息到表格
table_data.append({
"文件名": log_file,
"任务结束时刻": end_time,
"任务总计耗时": int(total_time),
"任务平均流量": avg_flow,
"记录写入速度": write_speed,
"读出记录总数": int(read_count),
"读写失败总数": int(write_failures)
})
# 将表格数据写入 CSV 文件
output_file = r"E:\Datax\datax\log\2021-10-13\output_table.csv"
with open(output_file, "w", newline="", encoding="utf-8") as csvfile:
fieldnames = ["文件名", "任务结束时刻", "任务总计耗时", "任务平均流量", "记录写入速度", "读出记录总数", "读写失败总数"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
# 写入表头
writer.writeheader()
# 写入数据
for row in table_data:
writer.writerow(row)
print(f"表格已保存至 {output_file}")
print("表", table_data)