我如何使用 grep 命令从日志文件中捕获相关 ID 以及 java 堆栈跟踪和多行消息

How can I use grep command to capture correlation ID along with java stacktrace and multiline message from log file

在日志文件中,每个发送的请求都会自动分配一个唯一的相关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 堆栈跟踪一起进行 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 命令可以做到吗?或者有没有其他推荐的工具?但是,我不允许在生产服务器上安装新包。操作系统为Red Hat 7.

尝试:

$ awk -F\| -v id='X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' '/^[0-9]{4}-[0-9]{2}-[0-9]{2} /{f=0} ==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'

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

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

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

  • ==id{f=1}

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

  • f

    如果 f 为真,打印该行。

希望对您有所帮助:

您可以在 grep 命令中使用 -C n,其中 n 是一个整数来确定 grep 单词周围的行数

grep 'X-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' file -C 10

会有帮助 它不会完全满足您的需求,但会有所帮助。