【工具类】正则表达式过滤器(过滤日志、过滤文件)

1. 【工具类】正则表达式过滤器(过滤日志、过滤文件)

  • 1. 【工具类】正则表达式过滤器(过滤日志、过滤文件)
    • 1.1. 划重点
    • 1.2. 参数说明
    • 1.3. 正则表达式 regular.json 内容如下
    • 1.4. 举例
    • 1.5. 代码说明

1.1. 划重点

功能: python实现的支持对文件进行正则表达式过滤,不同的过滤模板,维护不同的正则表达式文件即可,方便跨平台通用

  • 编写自己的正则表达式,主要填写 regexp 字段,并保存为 regular.json 文件,格式如下
[
{"id": "","regexp": ".*hello world.*","ignore":0,"add":"","time_id":""},
{"id": "","regexp": "^my name is knowledgebao.*","ignore":0,"add":"","time_id":""}
]
  • 将下边python代码保存为 filter_file.py 文件,准备要过滤的文件 test.log
  • 执行 python3 filter_file.py -i test.log -r regular.json -o output.log 其中 output.log 是过滤后的文件
#!/usr/bin/env python3
# -*- coding: utf-8 -*-import re
import argparse
import os
import logging
import json
import uuid
from datetime import datetimelogging.basicConfig(format='[%(asctime)s.%(msecs)03d] [%(levelname).1s] [%(filename)s:%(lineno)d] %(message)s',datefmt='%Y-%m-%d %H:%M:%S')
logger = logging.getLogger(__name__)#  日志级别设置
def set_log_level(level):log_levels = {0: logging.DEBUG,1: logging.INFO,2: logging.WARNING,3: logging.ERROR,4: logging.CRITICAL}if level in log_levels:logger.setLevel(log_levels[level])# 正则表达式解析结构体,对应 json 文件中的一条记录
class regexp_info:def __init__(self):self.id = None              # self.ignore = None          # self.add = None             # 额外添加在日志前边的字符串self.regexp_text = None     # 原始正则表达式内容self.regexp = None          # 编译后的正则表达式句柄self.time_id = None         # self.time = Nonedef __str__(self) -> str:return f"id: {self.id}, ignore: {self.ignore}, add: {self.add}, time_id: {self.time_id} regexp: {self.regexp_text}"# 常用正则表达式
class regexp_utils:# [15:48;00.224][I][0411 15:46:57.447] log infopattern_time1 = re.compile(r"^\[\d{2}:\d{2};\d{2}\.\d{3}\]\[.\]\[(\d{4} \d{2}:\d{2}:\d{2}\.\d{3})\]")# [E][0410 21:44:07.514][xxx][xxx] loginpattern_time2 = re.compile(r"^\[.\]\[(\d{4} \d{2}:\d{2}:\d{2}\.\d{3})\]")# 日志解析类,过滤日志文件
class filter_file:def __init__(self):self.regexps = {}    self.pattern_time = regexp_utils.pattern_time1self.f = Noneself.all_line = 0self.process_line = 0self.valid_line = 0# 解析正则表达式def parse_regexp(self, regexp_path, regexp_list, output):if regexp_path and os.path.exists(regexp_path):with open(regexp_path, 'r') as f:data = json.load(f)for val in data:info = regexp_info()info.id = val.get("id")info.ignore = val.get("ignore")info.add = val.get("add")  # .replace("\\n", "\n").replace("\\t", "\t")info.regexp_text = val.get("regexp")if info.regexp_text is None or info.regexp_text == "":continuetry:info.regexp = re.compile(info.regexp_text)except Exception as e:logger.error(f"regexp: {info.regexp_text} error: {e}")raise einfo.time_id = val.get("time_id")self.regexps[info.id] = infologger.info(f"{info}")if regexp_list:for regexp in regexp_list:if regexp is None or regexp == "":continueinfo = regexp_info()info.id = uuid.uuid4().hexinfo.regexp_text = ".*"+regexp+".*"try:info.regexp = re.compile(info.regexp_text)except Exception as e:logger.error(f"regexp: {info.regexp_text} error: {e}")raise eself.regexps[info.id] = infologger.info(f"{info}")if output:self.f = open(output, 'w+')def __write_file(self, text):if self.f and text and text != "":self.f.write(text)# return t1-t2def __get_time_delta(self, t1, t2):if t1 is None or t2 is None:return Noneif not (isinstance(t1, datetime) and isinstance(t2, datetime)):return Nonedelta_time = str(t1 - t2)if len(delta_time) < 14:delta_time += "."delta_time += "0" * (14-len(delta_time))delta_time += "_"return delta_timedef __process_time(self, line, regexp):time = Nonedate_time = self.pattern_time.findall(line)if len(date_time) > 0:time = datetime.strptime(date_time[0], '%m%d %H:%M:%S.%f')if regexp.time_id and regexp.time_id in self.regexps and self.regexps[regexp.time_id].time:delta = self.__get_time_delta(time, self.regexps[regexp.time_id].time)logger.debug(f"{delta}, {time}, {self.regexps[regexp.time_id].time}")self.__write_file(delta)return timedef __parse_line(self, line):self.valid_line += 1# logger.debug(f"beg process: {line}")for regexp in self.regexps.values():# logger.debug(f"regexp: {regexp}")if regexp.ignore or regexp.regexp is None or regexp.regexp_text == "":continueif regexp.regexp.search(line):logger.debug(f"{regexp.id}: {line}")if self.f:# 打印额外信息self.__write_file(regexp.add)# 获取和打印时间差regexp.time = self.__process_time(line, regexp)# 打印日志内容self.__write_file(line)self.process_line += 1breakdef parses(self, file_path):for line in open(file_path, "rb"):self.all_line += 1try:line = line.decode("utf8",errors="replace")if line and line != "":self.__parse_line(line)except Exception as e:logger.warning(f"parse lines {self.all_line} failed: {e}")# if self.all_line > 10:  # for test#     breakdef print_result(self):logger.info(f"all line: {self.all_line}, decode line: {self.valid_line}, process line: {self.process_line}")if __name__ == "__main__":parser = argparse.ArgumentParser()parser.description = 'please enter correct para'parser.add_argument("-i", "--file", help="log file", type=str)parser.add_argument("-r", "--regular_file", help="regular json file", type=str)parser.add_argument("-rl", "--regular_list", help="regular text, support many", type=str, nargs='+')parser.add_argument("-o", "--output", help="log output file", type=str, default="output.log")parser.add_argument("-l", "--log_level", help="0-4, debug,info,warning,error,critical", type=int, default=1)args = parser.parse_args()logger.info(f"log level {args.log_level}")logger.info(f"input file {args.file}")logger.info(f"output file {args.output}")logger.info(f"regular file {args.regular_file}")logger.info(f"regular_list {args.regular_list}")set_log_level(args.log_level)if not os.path.exists(args.file):logger.error(f"input log file {args.file} not exist")exit(1)log_process = filter_file()try:log_process.parse_regexp(args.regular_file, args.regular_list, args.output)logger.info(f"begin parse {args.file}")logger.info(f"==================================")log_process.parses(args.file)log_process.print_result()except Exception as e:logger.error(f"parse log file {args.file} failed: {e}")

1.2. 参数说明

➜  python filter_file.py --help
usage: filter_file.py [-h] [-i FILE] [-r REGULAR_FILE] [-rl REGULAR_LIST [REGULAR_LIST ...]] [-o OUTPUT] [-l LOG_LEVEL]please enter correct paraoptional arguments:-h, --help                                    show this help message and exit-i FILE, --file FILE                          log file-r REGULAR_FILE, --regular_file REGULAR_FILE  regular json file-rl REGULAR_LIST [REGULAR_LIST ...], --regular_list REGULAR_LIST [REGULAR_LIST ...]    regular text, support many-o OUTPUT, --output OUTPUT                    log output file-l LOG_LEVEL, --log_level LOG_LEVEL           0-4, debug,info,warning,error,critical
  • -i 原始待处理文件
  • -r regular_file,指定正则表达式文件
  • -rl regular_list, 指定正则表达式字符串,可以指定多个, 与 -r 类似,直接命令行输入正则表达式
  • -o 指定输出文件,默认是 output.log
  • -l 日志级别,默认是info

1.3. 正则表达式 regular.json 内容如下

[
{"id": "xxx","regexp": "xxxx","ignore":0,"add":"","time_id":""}
]
  • id 用来定义唯一标识,可用来关联其他条目,目前可以计算时间差
  • regexp 是正则表达式,用于过滤有效日志
  • ignore 表示是否忽略该行,0表示不忽略,1表示忽略
  • add 表示添加的字符串,比如添加换行符,添加在对应日志的前边
  • time_id 表示与哪个 id 关联,目前主要是用来计算时间差

1.4. 举例

  • 举例 python3 filter_file.py -i test.log -o output.log -r regular.json

reqular.json 内容如下

[
{"id": "001","regexp": ".*0000000000000.*","ignore":0,"add":"\n","time_id":""},
{"id": "002","regexp": ".*222222222.*","ignore":0,"add":"","time_id":""},
{"id": "003","regexp": ".*333333333.*","ignore":0,"add":"","time_id":"001"},
{"id": "004","regexp": ".*555555555.*","ignore":0,"add":"","time_id":""},
{"id": "005","regexp": ".*777777777.*","ignore":1,"add":"","time_id":""},
{"id": "006","regexp": ".*999999999.*","ignore":0,"add":"","time_id":"001"}
]

test.log 内容如下

[15:47;28.931][D][0411 15:43:21.040] log 0000000000000 ppfejf
[15:47;28.931][W][0411 15:43:21.040] log 1111111111111ppfejf
[15:47;28.931][I][0411 15:43:22.040] log 2222222222222ppfejf
[15:47;28.931][E][0411 15:43:23.040] log 33333333333333ppfejf
[15:47;28.931][D][0411 15:43:24.040] log 444444444444444ppfejf
[15:47;28.931][W][0411 15:43:24.040] log 555555555555555ppfejf
[15:47;28.931][I][0411 15:43:24.040] log 666666666666666fejf
[15:47;28.931][E][0411 15:43:24.040] log 3333333333333ppfejf
[15:47;28.931][D][0411 15:43:24.040] log 7777777777777777ppfejf
[15:47;28.931][W][0411 15:43:24.040] log 3333333333333ppfejf
[15:47;28.931][I][0411 15:43:24.040] log 888888888888888ppfejf
[15:47;28.931][E][0411 15:43:24.040] log 999999999999999ppfejf
[15:47;28.931][E][0411 15:43:24.040] log 3333333333333ppfejf

output.log 输出结果如下


[15:47;28.931][D][0411 15:43:21.040] log 0000000000000 ppfejf
[15:47;28.931][I][0411 15:43:22.040] log 2222222222222ppfejf
0:00:02.000000_[15:47;28.931][E][0411 15:43:23.040] log 33333333333333ppfejf
[15:47;28.931][W][0411 15:43:24.040] log 555555555555555ppfejf
0:00:03.000000_[15:47;28.931][E][0411 15:43:24.040] log 3333333333333ppfejf
0:00:03.000000_[15:47;28.931][W][0411 15:43:24.040] log 3333333333333ppfejf
0:00:03.000000_[15:47;28.931][E][0411 15:43:24.040] log 999999999999999ppfejf
0:00:03.000000_[15:47;28.931][E][0411 15:43:24.040] log 3333333333333ppfejf

1.5. 代码说明

  • set_log_level 用来设置日志级别
  • regexp_info 类,用来解析正则表达式
  • regexp_utils 类,常用正则表达式,比如解析获取文本中的时间等
  • filter_file 类,用来解析正则表达式,读文件,过滤每一行,还可以计算时间差

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/828230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTB Runner

Runner User Nmap ──(root㉿kali)-[/home/…/machine/SeasonV/linux/Runner] └─# nmap -A runner.htb -T 4 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-04-22 23:07 EDT Stats: 0:00:01 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Sca…

用户中心 -- 代码理解

一、删除表 & if 删除表 1.1 DROP TABLE IF EXISTS user 和 DROP TABLE user 网址&#xff1a; 用户管理第2节课 -- idea 2023.2 创建表--【本人】-CSDN博客 二、 代码 2.1 清空表中数据 的 命令 【truncate 清空】 网址&#xff1a; 用户管理第2节课 -- idea 2…

iOS开发进阶(二十):Xcode 断点调试详解

文章目录 一、前言二、断点调试技巧2.1 设置断点2.2 断点的自定义设置2.3 断点类型 一、前言 所谓断点&#xff0c;其实就是一个让应用暂停运行的机制&#xff0c;这是为了方便开发人员执行调试&#xff0c;查看寄存器的某些值。既然设置了断点&#xff0c;可以让应用停在某一…

Ajax和axios基础

AJAX Asynchronous JavaScript And XML 异步的JavaScript和XML 作用 数据交换: 通过Ajax可以给服务器发送请求,服务器将数据直接响应回给浏览器. 异步交互: 可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术. 同步和异步 同步发送请求: 浏览器发…

Linux中Ctrl+C和Ctrl+Z的区别_实战讲解(超详细)

1、CtrlC和CtrlZ的区别&#xff1a; CtrlZ&#xff1a;暂停进程 即挂起进程 暂停当前进程并将其放到后台。可以在后续恢复执行。 暂停的进程仍然占用系统内存 CtrlC&#xff1a;终止进程 终止进程后&#xff0c;程序代码占用的内存会释放掉 2、实战讲解 跑人工智能代码的时候…

redis故障中出现的缓存击穿、缓存穿透、缓存雪崩?

一、背景&#xff1a; 在维护redis服务过程中&#xff0c;经常遇见一些redis的名词&#xff0c;例如缓存击穿、缓存穿透、缓存雪崩等&#xff0c;但是不是很理解这些&#xff0c;如下就来解析一下缓存击穿、缓存穿透、缓存雪崩名词。 二、缓存穿透问题&#xff1a; 常见的缓存使…

flutter ios Firebase 消息通知错误 I-COR000005,I-FCM001000 解决

*前提是已经 使用firebase-tools 已经给 Flutter 加入了 消息通知相关配置。教程>> 一、I-COR000005 10.22.0 - [FirebaseCore][I-COR000005] No app has been configured yet. import Firebase....FirebaseApp.configure() 10.22.0 - [FirebaseMessaging][I-FCM001000…

mysql事故复盘: 单行字节最大阈值65535字节(原创)

背景 记得还在银行做开发&#xff0c;投产上线时&#xff0c;项目发版前&#xff0c;要提DDL的sql工单&#xff0c;mysql加1个字段&#xff0c;因为这张表为下游数据入湖入仓用的&#xff0c;长度较大。在测试库加字段没问题&#xff0c;但生产库字段加不上。 先说结论 投产…

QT初识

通过图形化界面输出helloworld 既然学习了QT&#xff0c;那么自然要做经典的输出helloworld字符串的实验。 QT有两好几种方案输出helloworld&#xff0c;一种是通过图形化界面输出&#xff0c;一种是通过代码实现。 这里先了解图形化界面的方案。 创建项目后&#xff0c;点…

LeetCode:2385. 感染二叉树需要的总时间(DFS Java)

目录 2385. 感染二叉树需要的总时间 题目描述&#xff1a; 实现代码与解析&#xff1a; DFS 原理思路&#xff1a; 2385. 感染二叉树需要的总时间 题目描述&#xff1a; 给你一棵二叉树的根节点 root &#xff0c;二叉树中节点的值 互不相同 。另给你一个整数 start 。在第…

【论文阅读】互连网络的负载平衡路由算法 (RLB RLBth)

前言Oblivious Load Balancing 不经意路由负载平衡 1. oblivious routing 不经意/无关路由的背景知识 1. oblivious routing, adaptive routing & minimal/non-minimal routing algorithms 2. Balancing a 1-Dimensional ring: RLB and RLBth 一维 ring 的 RLB and RLBth 1…

如何设计一个安全的系统架构?

本文转自 公众号 ByteByteGo&#xff0c;如有侵权&#xff0c;请联系&#xff0c;立即删除 如何设计一个安全的系统架构&#xff1f; 如何设计安全的系统&#xff1f;我们总结了 12 条原则供架构师们参考。 设计安全的系统非常重要&#xff0c;原因有很多&#xff0c;从保护敏…

SpringCloud系列(13)--Eureka服务名称修改和服务IP显示

前言&#xff1a;在上一章节中我们把服务提供者做成了集群&#xff0c;而本章节则是一些关于服务信息的配置&#xff0c;这部分知识对集群整体影响不大&#xff0c;不过最好还是掌握&#xff0c;毕竟万一有用到的地方呢 1、修改服务的名称 有时候我们想要修改服务的名称&#…

JavaSE学习文档(上)

JavaSE学习文档 第一章 Java概述1.2 计算机编程语言1.3 Java语言版本概述1.4 Java语言分类1.5 JDK,JRE,JVM的关系1.6 JDK安装1.7 DOS命令1.8 Java程序执行过程1.9 编写HelloWorld1.10 常见错误1.11 编写程序时要注意的点 第二章 Java基础语法2.1 Java中的注释文档注释 2.2 关键…

武汉星起航:亚马逊全球资源赋能中国卖家,跨境电商助力品牌国际化

亚马逊全球开店业务于2015年正式进驻中国&#xff0c;为中国卖家打开了通往全球市场的便捷之门。这一举措不仅为中国卖家提供了与全球消费者直接交流的机会&#xff0c;更借助亚马逊的丰富资源和先进技术&#xff0c;帮助卖家将优质的中国商品推向世界舞台。亚马逊平台以其高效…

Ant Design Vue + js 表格计算合计

1.需要计算的数量固定&#xff08;如表1&#xff0c;已知需要计算的金额为&#xff1a;装修履约保证金 装修垃圾清运费出入证工本费 出入证押金 这四项相加&#xff0c;可以写成固定的算法&#xff09;&#xff1a; 表格样式&#xff1a; <h4 style"margin: 0 0 8px…

Bayes判别示例数据:鸢尾花数据集

使用Bayes判别的R语言实例通常涉及使用朴素贝叶斯分类器。朴素贝叶斯分类器是一种简单的概率分类器&#xff0c;基于贝叶斯定理和特征之间的独立性假设。在R中&#xff0c;我们可以使用e1071包中的naiveBayes函数来实现这一算法。下面&#xff0c;我将通过一个简单的示例展示如…

《生成式AI导论》学习笔记

1.课程定位 2.什么是生成式人工智慧&#xff1f; 3. 今日的生成式人工智慧厉害在哪里&#xff1f; 4.训练不了人工智慧&#xff1f;那我训练自己 5.训练不了人工智慧&#xff1f;你可以训练你自己&#xff08;中&#xff09;——拆解问题使用工具 6.大语言模型修炼史——第一阶…

微信小程序使用echarts组件实现饼状统计图功能

微信小程序使用echarts组件实现饼状统计图功能 使用echarts实现在微信小程序中统计图的功能&#xff0c;具体的实现步骤思路可进我主页查看我的另一篇博文https://blog.csdn.net/weixin_45465881/article/details/138171153进行查看&#xff0c;本篇文章主要使用echarts组件实…

Redis(六) Set集合类型

文章目录 前言命令SADDSMEMBERSSISMEMBERSCARDSPOPSMOVESREM集合间操作SINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE 命令小结 内部编码使用场景 前言 集合类型也是保存多个字符串类型的元素的&#xff0c;和列表类型不同的是&#xff0c;set集合类型中的元素是无序的且…