根据结构化文本过滤日志

问题描述 投票:0回答:1

我有许多日志文件,每一行都遵循相同的模式,如下所示:

<TimeStamp> <Thread> <Marker> - <Message>

我想按线程值过滤这些日志并保存在名为 .log

的新文件中

例如,假设我们有一个文件 log12.log:

...
18:37:06.9178 main ClassA - "....."
18:37.07.2267 thread-1 ClassB - "....."
18:37.07.7797 thread-2 ClassC - "....."
18:37.08.0867 thread-1 ClassB - "....."
18:37:16.9231 main ClassA - "....."
...

在不访问文件并知道日志文件中存在哪些线程的情况下,我正在寻找一种方法将日志文件过滤到仅包含特定线程的新文件中。

所以在这种情况下我们会:

主.日志

...
18:37:06.9178 main ClassA - "....."
18:37:16.9231 main ClassA - "....."
...

线程1.log

...
18:37.07.2267 thread-1 ClassB - "....."
18:37.08.0867 thread-1 ClassB - "....."
...

线程2.log

...
18:37.07.7797 thread-2 ClassC - "....."
...

在这种情况下我尝试使用 grep,但是当我不完全知道我要过滤的内容时,我不确定该怎么做

unix logging awk grep
1个回答
0
投票

如果生成的日志文件数量没有大到超过系统上进程可以同时打开的最大数量,请使用任何 awk:

$ awk '{print > ($2 ".log")}' log12.log

$ head main.log thread*.log
==> main.log <==
18:37:06.9178 main ClassA - "....."
18:37:16.9231 main ClassA - "....."

==> thread-1.log <==
18:37.07.2267 thread-1 ClassB - "....."
18:37.08.0867 thread-1 ClassB - "....."

==> thread-2.log <==
18:37.07.7797 thread-2 ClassC - "....."

如果您要生成大量输出文件,那么您可以使用上面的脚本使用 GNU awk 在内部处理它,或者再次使用任何 awk,您可以这样做,但它会很慢,因为它打开/关闭输出一次每行输入:

awk '{out=$2 ".log"} !seen[out]++{printf "" > out} {print >> out; close(out)}' log12.log

或者,更有效的是,使用 Decorate-Sort-Undecorate 习惯用法,每个输出文件仅打开/关闭输出一次:

awk -v OFS='\t' '{print $2, NR, $0}' log12.log |
    sort -k1,1 -k2,2n |
    cut -f3- |
    awk '$2!=prev{close(out); out=$2 ".log"; prev=$2} {print > out}'
© www.soinside.com 2019 - 2024. All rights reserved.