使用 log4j2 进行结构化日志记录
编辑使用 log4j2 进行结构化日志记录编辑
通过利用 log4j2 的 MapMessage
,甚至通过实现自己的支持 JSON 的 MultiformatMessage
,您可以向生成的 JSON 添加额外的字段。
示例
logger.info(new StringMapMessage() .with("message", "Hello World!") .with("foo", "bar"));
如果类路径上存在 Jackson,您还可以使用 ObjectMessage
将自定义对象添加到生成的 JSON 中。
logger.info(new ObjectMessage(myObject));
myObject
变量引用了一个自定义对象,该对象可以由 Jackson ObjectMapper
序列化。
使用任一方法将在日志事件的顶层(而不是嵌套在 message
下)合并对象(如果它是 JSON 对象)。如果它是一个字符串、数字、布尔值或数组,它将被转换为字符串并作为 message
属性添加。这种转换避免了映射冲突,因为 message
在 Elasticsearch 映射中被类型化为字符串。
提示编辑
我们建议使用现有的 ECS 字段.
如果没有合适的 ECS 字段,请考虑为您的字段添加前缀 labels.
,例如 labels.foo
,用于简单的键值对。对于嵌套结构,请考虑添加前缀 custom.
。这种方法可以防止在 ECS 以后添加相同字段但使用不同映射的情况下发生冲突。
需要注意的地方编辑
一个常见的陷阱是 Elasticsearch 如何处理字段名称中的点,以及它们如何影响映射。在最近的 Elasticsearch 版本中,以下 JSON 结构将导致相同的索引映射
{ "foo.bar": "baz" }
{ "foo": { "bar": "baz" } }
属性 foo
将映射到 对象数据类型.
这意味着您不能索引一个文档,其中 foo
可能是不同的数据类型,如下面的示例所示
{ "foo": "bar" }
在该示例中,foo
是一个字符串。尝试索引该文档会导致错误,因为 foo
的数据类型不能同时为对象和字符串。