git*_*rty 8 java regex algorithm logging awk
描述很长,所以请耐心等待:
我的日志文件大小从300 mb到1.5 Gb,需要使用搜索键进行过滤.
日志的格式如下:
24 May 2017 17:00:06,827 [INFO] 123456 (Blah : Blah1) Service-name:: Single line content
24 May 2017 17:00:06,828 [INFO] 567890 (Blah : Blah1) Service-name:: Content( May span multiple lines)
24 May 2017 17:00:06,829 [INFO] 123456 (Blah : Blah2) Service-name: Multiple line content. Printing Object[ ID1=fac-adasd ID2=123231
ID3=123108 Status=Unknown
Code=530007 Dest=CA
]
24 May 2017 17:00:06,830 [INFO] 123456 (Blah : Blah1) Service-name:: Single line content
4 May 2017 17:00:06,831 [INFO] 567890 (Blah : Blah2) Service-name:: Content( May span multiple lines)
Run Code Online (Sandbox Code Playgroud)
给定搜索键123456,我需要获取以下内容:
24 May 2017 17:00:06,827 [INFO] 123456 (Blah : Blah1) Service-name:: Single line content
24 May 2017 17:00:06,829 [INFO] 123456 (Blah : Blah2) Service-name: Multiple line content. Printing Object[ ID1=fac-adasd ID2=123231
ID3=123108 Status=Unknown
Code=530007 Dest=CA
]
24 May 2017 17:00:06,830 [INFO] 123456 (Blah : Blah1) Service-name:: Single line content
Run Code Online (Sandbox Code Playgroud)
以下awk脚本完成我的工作(非常缓慢):
gawk '/([0-9]{1}|[0-9]{2})\s\w+\s[0-9]{4}/{n=0}/123456/{n=1} n'
Run Code Online (Sandbox Code Playgroud)
搜索1 GB大小的日志文件大约需要8分钟.我需要为许多这样的文件执行此操作.最重要的是,我有多个这样的搜索键,这使整个任务变得不可能.
我最初的解决方案是使用多线程.我使用了fixedThreadPoolExecutor,为每个需要过滤的文件提交了一个任务.在任务描述中,我使用java的Runtime()生成了新进程,它将使用bash执行gawk脚本并将输出写入文件然后合并所有文件.
虽然这似乎是一种糟糕的方式,但由于过滤依赖于I/O而不是CPU,因此与按顺序在每个文件上执行脚本相比,它确实给了我加速.
但它仍然是不够的,因为整个事情需要2小时,对于一个搜索密钥,有27GB的日志文件.平均而言,我有4个这样的搜索键,需要获取所有结果并将它们组合在一起.
我的方法效率不高,因为:
A)当给出多个搜索关键字时,它会多次访问每个日志文件,并导致更多的I/O开销.
B)它会产生在每个线程内创建进程的开销.
所有这一切的简单解决方案是使用一些正则表达式库从远离awk并在java中完成整个事情.这里的问题是什么是可以为我提供所需输出的正则表达式库?
使用awk,我有一个/filter/{action}
属性,可以让我指定要捕获的多行范围(如上所示).我怎样才能在java中做同样的事情?
我愿意接受各种建议.例如,一个极端的选择是将日志文件存储在像S3这样的共享文件系统中,并使用多台计算机处理输出.
我是stackoverflow的新手,我甚至不知道我是否可以在这里发布.但过去一周我一直在研究这个问题,我需要有专业知识的人来指导我.提前致谢.
你有几个选择。
在我看来,最好的方法是使用一本反向字典。这意味着对于至少一个日志中存在的每个关键字 x,您存储对包含它的所有日志的引用。但由于您已经在这项任务上花费了一周的时间,因此我建议您使用已经存在的东西并且可以做到这一点:Elasticsearch。实际上,您可以使用完整的 ELK 堆栈(elasticsearch、logstash、kibana - 主要为日志设计)来解析日志,因为您只需在配置文件中放置正则表达式即可。您只需要对文件建立索引一次,搜索速度将快至几毫秒。
如果你确实想浪费精力而不去寻求最佳解决方案,你可以使用hadoop上的map-reduce来过滤日志。但这并不是 Map-Reduce 最佳的任务,它更像是一种黑客攻击。
归档时间: |
|
查看次数: |
297 次 |
最近记录: |