我想将API请求/响应记录为json格式。
预期的LogEntry类似于
{
"timestamp" : "...",
"level" : "DEBUG",
"headers" : [
"header1" : "value1",
"header2" : "value2",
"header3" : "value3"
],
"requestPayload" : "<Request Json>" // prefereablly as sub-document, worst case string is fine.
"labels" : [ //key fields which can be used for searching the logentry
"searchField1" : "....",
"searchField2" : "....",
"searchField3" : "...."
]
}
我的问题是:
使用Logback,如何将嵌套字段(例如上面示例中的标题,标签,requestPaylod)记录为json子文档。我尝试过MDC,但它仅限于 仅限'String,String'的映射,并将第一级之后的所有字段视为String。
我讨厌为此编写我的自定义记录器,并希望使用成熟的日志记录框架(logback / log4j)来控制日志记录级别,时间戳记日志事件等。
答案 0 :(得分:1)
您可以在任何Logback appender中使用logback-contrib's 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类提供了一个扩展点,允许您更改属性名称通过扩展JsonLayout
并覆盖toJsonMap()
来生成JSON。
编辑1 :解决你的回复(“我的问题更多的是关于如何实现json子文档/嵌套,如上所述.MDC仅限于地图”)...你可以将复杂的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"}
答案 1 :(得分:0)
对于请求/响应日志记录,请尝试Logbook和logstash-logback-encoder。您将能够使用标记来添加结构化内容。
为了在JSON结构中添加“您自己的”字段,我编写了一个您可能感兴趣的代码生成器,它添加了构建器支持:json-log-domain