你可以在任何 Logback appender中使用logback-contrib 。 JsonLayout
例如:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>false</prettyPrint>
</jsonFormatter>
<timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
<appendLineSeparator>true</appendLineSeparator>
</layout>
</appender>
给定这样的日志语句...
MDC.put("header1", "headerValue1");
logger.info("hello!");
logger.info("good bye!");
... 的使用JsonLayout
会导致 Logback 写成这样:
{"timestamp":"2017-08-15 09:06:41.813","level":"INFO","thread":"main","mdc":{"header1":"headerValue1"},"logger":"com.stackoverflow.logback.LogbackTest","message":"hello!","context":"default"}
{"timestamp":"2017-08-15 09:06:41.887","level":"INFO","thread":"main","mdc":{"header1":"headerValue1"},"logger":"com.stackoverflow.logback.LogbackTest","message":"good bye!","context":"default"}
我认为这符合将日志事件写入 JSON 文档的要求,同时仍保留 Logback 的行为,例如“控制日志记录级别、时间戳日志事件等”。有一些对更改 JSON 格式的内置支持(例如,您可以包含/排除上下文、记录器名称等),但 JsonLayout 类提供了一个扩展点,允许您通过扩展和覆盖来更改生成的 JSON 中的属性名称. JsonLayout
toJsonMap()
编辑 1:解决您的回复(“我的问题更多是关于如何实现所提到的 json 子文档/嵌套。MDC 仅限于 map of only”)...您可以将复杂的 MDC 值序列化为 JSON 并添加序列化的 JSON 表示到 MDC。例如:
Map<String, Object> complexMdcValue = new HashMap<>();
Map<String, Object> childMdcValue = new HashMap<>();
childMdcValue.put("name", "Joe");
childMdcValue.put("type", "Martian");
complexMdcValue.put("child", childMdcValue);
complexMdcValue.put("category", "etc");
MDC.put("complexNestedValue", objectMapper.writeValueAsString(complexMdcValue));
logger.info("hello!");
将产生此输出(其中 MVC 记录的键“complexNestedValue”是包含子文档的 JSON):
{"timestamp":"2017-08-27 18:03:46.706","level":"INFO","thread":"main","mdc":{"complexNestedValue":"{\"category\":\"etc\",\"child\":{\"name\":\"Joe\",\"type\":\"Martian\"}}"},"logger":"com.stackoverflow.logback.LogbackTest","message":"hello!","context":"default"}