Datadog grok 自定义 java 堆栈解析和有序列表字段
Datadog grok custom java stack parsing and ordered list fields
我在 datadog 的 grok 管道中有以下日志示例:
2022-05-10 11:26:58 [SEVERE]: Log from eu.myapp
dev added message - eu.myapp.Controller.<init>
java.lang.NullPointerException
at eu.myapp.Controller.<init>(Controller.java:48)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
和下面的简单解析规则
log %{_date}%{space}\[%{_status}\]\:%{space}%{data:logger}(\n%{space}%{data:msg}%{space}-%{space}%{data:in})?(\n%{space}%{data:error.msg})?(\n%{space}%{data:error.stack})?
并尝试通过重复 error.stack 使每一行都添加到数组
log %{_date}%{space}\[%{_status}\]\:%{space}%{data:logger}(\n%{space}%{data:msg}%{space}-%{space}%{data:in})?(\n%{space}%{data:error.msg})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})
输出简单:
{
"level": "SEVERE",
"timestamp": 1652182018000,
"error": {
"msg": "java.lang.NullPointerException",
"stack": "at eu.myapp.Controller.<init>(Controller.java:48)\n at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)\n at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)\n at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)\n at java.lang.reflect.Constructor.newInstance(Constructor.java:423)"
},
"in": "eu.myapp.Controller.<init>",
"msg": "dev added message",
"logger": "Log from eu.myapp"
}
输出更好:
{
"level": "SEVERE",
"timestamp": 1652182018000,
"error": {
"msg": "java.lang.NullPointerException",
"stack": [
"at java.lang.reflect.Constructor.newInstance(Constructor.java:423)",
"at eu.myapp.Controller.<init>(Controller.java:48)",
"at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)",
"at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)",
"at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)"
]
},
"in": "eu.myapp.Controller.<init>",
"msg": "dev added message",
"logger": "Log from eu.myapp"
}
如您所见,更好的输出更具可读性,但列表现在是无序的。有什么方法可以让 error.stack 订购吗?或者比我现在做的更好地分析这种情况的任何其他提示或技巧。
我必须注意,我无法控制日志文件的生成或格式。
整个堆栈跟踪应该在 error.msg
属性内。
所以你可以更新你的 grok 解析器到这个(你可以放回你的状态和日期助手规则)。
log %{date("yyyy-MM-dd HH:mm:ss"):timestamp}%{space}\[%{word:status}\]\:%{space}%{data:logger}(\n%{space}%{data:msg}%{space}-%{space}%{data:in})?(\n%{data:error.msg})?
我还建议将 msg
重命名为 message
,将 error.msg
重命名为 error.stack
。您可以看到它们在文档中被列为 reserved attribute。这将使堆栈跟踪变得漂亮UI,看起来更清晰。
还记得在您的管道中创建 message, status, and date 重新映射器,以便您的日志的默认值全部得到适当更新。
我在 datadog 的 grok 管道中有以下日志示例:
2022-05-10 11:26:58 [SEVERE]: Log from eu.myapp
dev added message - eu.myapp.Controller.<init>
java.lang.NullPointerException
at eu.myapp.Controller.<init>(Controller.java:48)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
和下面的简单解析规则
log %{_date}%{space}\[%{_status}\]\:%{space}%{data:logger}(\n%{space}%{data:msg}%{space}-%{space}%{data:in})?(\n%{space}%{data:error.msg})?(\n%{space}%{data:error.stack})?
并尝试通过重复 error.stack 使每一行都添加到数组
log %{_date}%{space}\[%{_status}\]\:%{space}%{data:logger}(\n%{space}%{data:msg}%{space}-%{space}%{data:in})?(\n%{space}%{data:error.msg})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})?(\n%{space}%{data:error.stack})
输出简单:
{
"level": "SEVERE",
"timestamp": 1652182018000,
"error": {
"msg": "java.lang.NullPointerException",
"stack": "at eu.myapp.Controller.<init>(Controller.java:48)\n at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)\n at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)\n at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)\n at java.lang.reflect.Constructor.newInstance(Constructor.java:423)"
},
"in": "eu.myapp.Controller.<init>",
"msg": "dev added message",
"logger": "Log from eu.myapp"
}
输出更好:
{
"level": "SEVERE",
"timestamp": 1652182018000,
"error": {
"msg": "java.lang.NullPointerException",
"stack": [
"at java.lang.reflect.Constructor.newInstance(Constructor.java:423)",
"at eu.myapp.Controller.<init>(Controller.java:48)",
"at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)",
"at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)",
"at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)"
]
},
"in": "eu.myapp.Controller.<init>",
"msg": "dev added message",
"logger": "Log from eu.myapp"
}
如您所见,更好的输出更具可读性,但列表现在是无序的。有什么方法可以让 error.stack 订购吗?或者比我现在做的更好地分析这种情况的任何其他提示或技巧。
我必须注意,我无法控制日志文件的生成或格式。
整个堆栈跟踪应该在 error.msg
属性内。
所以你可以更新你的 grok 解析器到这个(你可以放回你的状态和日期助手规则)。
log %{date("yyyy-MM-dd HH:mm:ss"):timestamp}%{space}\[%{word:status}\]\:%{space}%{data:logger}(\n%{space}%{data:msg}%{space}-%{space}%{data:in})?(\n%{data:error.msg})?
我还建议将 msg
重命名为 message
,将 error.msg
重命名为 error.stack
。您可以看到它们在文档中被列为 reserved attribute。这将使堆栈跟踪变得漂亮UI,看起来更清晰。
还记得在您的管道中创建 message, status, and date 重新映射器,以便您的日志的默认值全部得到适当更新。