按线程分析日志文件的节



假设下面这样的示例日志文件是由Java程序中的几个线程异步写入的。

使用grep/sed/awk/perl这样的工具,有没有一种简单的方法可以解析出仅与[ServerThread-4]行相关的所有信息,以及随后可能与该线程相关的任何XML数据。

但我不想要任何[ServerThread-10](或其他线程(行,也不想要那些不相关线程的行之后的任何XML数据。

我试着像这样使用sed和awk,但这些都不起作用,大概是因为我的开始和结束标记是一样的:

sed -n "/[ServerThread-4]/,/[ServerThread-4]/p" file.log > file-sed.log
awk "/[ServerThread-4]/{flag=1;next}/[ServerThread-4]/{flag=0}flag" file.log > file-awk.log

示例文件:

2020-09-22 18:06:24,333 [ServerThread-10] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-10,Request,7,linecount=2
2020-09-22 18:06:24,334 [ServerThread-10] DEBUG com.company.abc.webservice.wsc - Web service transfer time out set to: 130000 (ms)
2020-09-22 18:06:24,563 [ServerThread-4] DEBUG com.company.abc.function - XYZ Function Handler: class com.company.abc.function.XYZCalcDocHandler
2020-09-22 18:06:24,563 [ServerThread-4] DEBUG com.company.abc.function - num row 1
2020-09-22 18:06:24,563 [ServerThread-4] DEBUG com.company.abc.function - TAX_PER_ITEM
2020-09-22 18:06:24,564 [ServerThread-4] DEBUG com.company.abc.function - Request XYZ XML
<SOME_XML><ITEM>THREAD-4-DATA</ITEM></SOME_XML>
2020-09-22 18:06:24,564 [ServerThread-4] DEBUG com.company.abc.function - Using transform: quote.xsl
2020-09-22 18:06:24,569 [ServerThread-4] DEBUG com.company.abc.function - transformXml() = 5 (ms)
2020-09-22 18:06:24,569 [ServerThread-4] DEBUG com.company.abc.function - Request XML
<?xml version="1.0" encoding="UTF-8"?>
<DataEnvelope xmlns="urn:inc:blah:tps:7:0">
<OtherXml>
<Element>Thread-4-Data</Element>
</OtherXml>
</DataEnvelope>
2020-09-22 18:06:24,569 [ServerThread-4] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-4,Request,6,linecount=1
2020-09-22 18:06:24,569 [ServerThread-4] DEBUG com.company.abc.webservice.wsc - Web service transfer time out set to: 130000 (ms)
2020-09-22 18:06:24,669 [ServerThread-10] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-10,Send,335,linecount=2
2020-09-22 18:06:24,669 [ServerThread-10] INFO  com.company.abc.function - Process response
2020-09-22 18:06:24,670 [ServerThread-10] DEBUG com.company.abc.function - Response XML
<DataEnvelope>
<Login>Thread-10-User</Login>
</DataEnvelope>
2020-09-22 18:06:24,670 [ServerThread-10] DEBUG com.company.abc.function - Processing response line items
2020-09-22 18:06:24,670 [ServerThread-10] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-10,Response,1,linecount=2
2020-09-22 18:06:24,671 [ServerThread-10] DEBUG com.company.abc.function - Response XYZ XML
<CALCULATE_DATA><CLIENT>100</CLIENT><COMPANY>1000</COMPANY></CALCULATE_DATA>
2020-09-22 18:06:24,671 [ServerThread-10] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-10,Total,345,linecount=2
2020-09-22 18:06:24,923 [ServerThread-4] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-4,Send,354,linecount=1
2020-09-22 18:06:24,923 [ServerThread-4] INFO  com.company.abc.function - Process response
2020-09-22 18:06:24,923 [ServerThread-4] DEBUG com.company.abc.function - Normalizing CDATA elements
2020-09-22 18:06:24,923 [ServerThread-4] DEBUG com.company.abc.function - Response XML
<DataEnvelope>
<Login>Thread-4-User</Login>
</DataEnvelope>
2020-09-22 18:06:24,923 [ServerThread-4] DEBUG com.company.abc.function - Processing response line items
2020-09-22 18:06:24,924 [ServerThread-4] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-4,Response,1,linecount=1
2020-09-22 18:06:24,924 [ServerThread-4] DEBUG com.company.abc.function - Response XYZ XML
<CALCULATE_DATA><CLIENT>200</CLIENT><COMPANY>2000</COMPANY></CALCULATE_DATA>
2020-09-22 18:06:24,924 [ServerThread-4] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-4,Total,361,linecount=1

问题中有一些我不确定的地方,包括所需输出的形式。

如果您希望所有的行都以包含[ServerThread-4]的行开头和之后,直到包含[ServerThread-N]的任何一行,其中N不是4,那么您可以使用Perl的范围运算符

perl -wne'print if /[ServerThread-4]/ .. /[ServerThread-[^4]+]/ 
and not /[ServerThread-( [^4][0-9]* | 4[0-9]+ )]/x' file 

这产生了我认为需要的输出,如下所示,但请参见注释

这种方法做了一些假设,所以请检查一下它的效果如何。最重要的是,它假设每个ServerThread-N的部分是完全分离的,彼此分离(而不是混合(。

文件是">由几个线程异步写入";虽然有点吓人;这些线程组装它们的输出,然后使用一些基于线程的"块"来编写这些块;锁";(或锁定每次打印(,或将这些输出块发送到主线程,主线程会按顺序写入它们,或发送以某种方式标记的单行。。。?

如果线程只是在行到达时将其转储到磁盘,那么一个就不能再可靠地将输出部分从各个线程中分离出来。即使是单独的行也可能重叠并被破坏,因为不同的执行线程盲目地去往同一个资源。

上面一行的输出,在提供的文件上

2020-09-22 18:06:24,563 [ServerThread-4] DEBUG com.company.abc.function - XYZ Function Handler: class com.company.abc.function.XYZCalcDocHandler
2020-09-22 18:06:24,563 [ServerThread-4] DEBUG com.company.abc.function - num row 1
2020-09-22 18:06:24,563 [ServerThread-4] DEBUG com.company.abc.function - TAX_PER_ITEM
2020-09-22 18:06:24,564 [ServerThread-4] DEBUG com.company.abc.function - Request XYZ XML
<SOME_XML><ITEM>THREAD-4-DATA</ITEM></SOME_XML>
2020-09-22 18:06:24,564 [ServerThread-4] DEBUG com.company.abc.function - Using transform: quote.xsl
2020-09-22 18:06:24,569 [ServerThread-4] DEBUG com.company.abc.function - transformXml() = 5 (ms)
2020-09-22 18:06:24,569 [ServerThread-4] DEBUG com.company.abc.function - Request XML
<?xml version="1.0" encoding="UTF-8"?>
<DataEnvelope xmlns="urn:inc:blah:tps:7:0">
<OtherXml>
<Element>Thread-4-Data</Element>
</OtherXml>
</DataEnvelope>
2020-09-22 18:06:24,569 [ServerThread-4] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-4,Request,6,linecount=1
2020-09-22 18:06:24,569 [ServerThread-4] DEBUG com.company.abc.webservice.wsc - Web service transfer time out set to: 130000 (ms)
2020-09-22 18:06:24,923 [ServerThread-4] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-4,Send,354,linecount=1
2020-09-22 18:06:24,923 [ServerThread-4] INFO  com.company.abc.function - Process response
2020-09-22 18:06:24,923 [ServerThread-4] DEBUG com.company.abc.function - Normalizing CDATA elements
2020-09-22 18:06:24,923 [ServerThread-4] DEBUG com.company.abc.function - Response XML
<DataEnvelope>
<Login>Thread-4-User</Login>
</DataEnvelope>
2020-09-22 18:06:24,923 [ServerThread-4] DEBUG com.company.abc.function - Processing response line items
2020-09-22 18:06:24,924 [ServerThread-4] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-4,Response,1,linecount=1
2020-09-22 18:06:24,924 [ServerThread-4] DEBUG com.company.abc.function - Response XYZ XML
<CALCULATE_DATA><CLIENT>200</CLIENT><COMPANY>2000</COMPANY></CALCULATE_DATA>
2020-09-22 18:06:24,924 [ServerThread-4] DEBUG com.company.abc.Time - CALCULATE_DATA,ServerThread-4,Total,361,linecount=1

(我在测试文件中添加了带有[ServerThread-14]...-40的行(


注意两个额外的条件(在正则表达式的交替中(,而不是建立范围的条件。第一个,明确地排除了带有关闭范围运算符的短语的行,因为

范围运算符保持为true,直到右操作数为true,AFTER范围运算符变为false

相反,我们可以使用这样一个事实,即范围运算符返回范围中的序列号(当为false时为空字符串(,该序列号在最后一行附加了E0。这正是为了检查范围的最后一行(当结束标记求值为true时(。然后我们可以做

perl -wne' print if 
$r = /[ServerThread-4]/ .. /[ServerThread-([^4][0-9]*|4[0-9]+)]/ 
and not $r =~ /E0/
' file

第二个额外的条件现在被移动到结束标记的正则表达式中作为替换。为了排除4开始然后有更多数字(如ServerThread-40(的服务器线程号,这仍然让这有点笨拙。但如果不需要这个条件(很可能(,那么这会进一步简化,使用E0确实会给我们一个更好的表达式。

只有当我们假设线程4的数据没有与另一个线程的数据混合时,您的请求才是可能的。没有理由相信这种假设会一直存在,但我们对此无能为力。

my $target_id = 4;
my $print = 0;
while (<>) {
if ( my ($id) = /^d{4}-d{2}-d{2} d{2}:d{2}:d{2},d{3} [ServerThread-(d+)]/a) {
$print = $id == $target_id;
}
print if $print;
}

;一个衬垫":

perl -ne'
$print = $1 == 4 if /^d{4}-d{2}-d{2} d{2}:d{2}:d{2},d{3} [ServerThread-(d+)]/a;
print if $print;
'

作为缩短的";一个衬垫":

perl -ne'$p = $1 == 4 if /^.{24}[ServerThread-(d+)]/; print if $p'

如果我们允许自定义号码:

perl -sne'$p = $1 == $targ if /^.{24}[ServerThread-(d+)]/; print if $p' -- -targ=4

换行符可以删除或保留在中

指定要处理的文件到Perl一行

最新更新