首页 > 解决方案 > 如何使用 grep 命令从日志文件中捕获相关 ID 以及 java stacktrace 和多行消息

问题描述

在日志文件中,发送的每个请求都会自动分配一个唯一的相关 ID,例如X-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaX-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb如下面的 log4j 创建的日志示例所示。

2019-06-03 11:27:22,697|X-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|INFO |com.example.ExampleService|Start execute
2019-06-03 11:27:22,697|X-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|INFO |com.example.ExampleService|ENTRY| performIntegration()
2019-06-03 11:27:20,759|X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|INFO |com.example.ExampleService|EXIT| executeService()
2019-06-03 11:27:20,759|X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|INFO |com.example.ExampleService|EXIT| MyObject = This,
is
a
multiline log
message
2019-06-03 11:27:20,759|X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|ERROR|com.example.ExampleAdapter|error
com.example.ABCRuntimeException: Network error
    at ...
    at ...
Caused by: ...
    at ...
    at ...
2019-06-03 11:27:22,698|X-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|INFO |com.example.ExampleService|EXIT| performIntegration()
2019-06-03 11:27:22,699|X-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|INFO |com.example.ExampleService|EXIT| executeService()
2019-06-03 11:27:22,699|X-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|ERROR|com.example.ExampleAdapter| another error
com.example.ABCRuntimeException: Network error
    at ...
    at ...
Caused by: ...
    at ...
    at ...

如何将相关 id 与多行消息和 java stacktrace 一起grep?例如我想 grep X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,那么预期的输出应该如下

2019-06-03 11:27:20,759|X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|INFO |com.example.ExampleService|EXIT| executeService()
2019-06-03 11:27:20,759|X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|INFO |com.example.ExampleService|EXIT| MyObject = This,
is
a
multiline log
message
2019-06-03 11:27:20,759|X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|ERROR|com.example.ExampleAdapter|error
com.example.ABCRuntimeException: Network error
    at ...
    at ...
Caused by: ...
    at ...
    at ...

linux grep 命令能够实现这一点吗?或者有没有其他推荐的工具?但是,我不允许在生产服务器上安装新软件包。操作系统是红帽 7。

标签: javaunixexceptiongrepstack-trace

解决方案


尝试:

$ awk -F\| -v id='X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' '/^[0-9]{4}-[0-9]{2}-[0-9]{2} /{f=0} $2==id{f=1} f' file
2019-06-03 11:27:20,759|X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|INFO |com.example.ExampleService|EXIT| executeService()
2019-06-03 11:27:20,759|X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|INFO |com.example.ExampleService|EXIT| MyObject = This,
is
a
multiline log
message
2019-06-03 11:27:20,759|X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb|ERROR|com.example.ExampleAdapter|error
com.example.ABCRuntimeException: Network error
    at ...
    at ...
Caused by: ...
    at ...
    at ...

这个怎么运作

  • -F\|

    用作|字段分隔符。

  • -v id='X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'

    创建一个名为的 awk 变量id并为其分配感兴趣的 id。

  • /^[0-9]{4}-[0-9]{2}-[0-9]{2} /{f=0}

    如果当前行以日期开头,请将变量设置f为 false(零)。

  • $2==id{f=1}

    如果第二个字段与所需的 id 匹配,则将变量设置f为 true(一)。

  • f

    如果f为真,则打印该行。


推荐阅读