使用 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 的数据类型不能同时为对象和字符串。