使用 Spring Boot可以通过提供如下文件来2.1.1.RELEASE
将日志格式化为 JSON :logback-spring.xml
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
<timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>true</prettyPrint>
</jsonFormatter>
</layout>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="stdout" />
</root>
并添加到pom.xml
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-json-classic</artifactId>
<version>0.1.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
<artifactId>logback-jackson</artifactId>
<version>0.1.5</version>
</dependency>
确实导致如下消息:
{
"timestamp" : "2018-12-11T18:20:25.641Z",
"level" : "INFO",
"thread" : "main",
"logger" : "com.netflix.config.sources.URLConfigurationSource",
"message" : "To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.",
"context" : "default"
}
为什么?
我正在试用logz.io,当日志为 JSON 格式时,它的表现似乎更有利,一些托运人在处理多行日志时遇到了困难,就像我们在 java 堆栈跟踪中看到的那样,当以 JSON 格式格式化时,它可以自动解析字段,例如level
,message
如果有它会自动获取 MDC 数据。
我在一些将日志传送到 logzio 的方法方面有一些不太好的经验,比如他们的 docker 映像和使用 rsyslog 而不使用 JSON 格式的日志消息。
这种方法的问题
它适用于控制台附加,但 spring boot 提供了logging.file=test.log
, logging.level.com.example=WARN
, logging.pattern.console
. 我确实可以导入托管配置,spring-boot-2.1.1.RELEASE.jar!/org/springframework/boot/logging/logback/base.xml
然后从中导入console-appender.xml and
file-appender.xml`。
控制台附加程序的示例
<included>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
</included>
文件追加器的示例
<included>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
<maxHistory>${LOG_FILE_MAX_HISTORY:-0}</maxHistory>
</rollingPolicy>
</appender>
</included>
这两个正是我支持属性的弹簧配置所需要的,但它们不包括我需要的编码器/布局。
在我的初始测试中,我不能简单地将我的 appender 命名为与那些相同的名称并提供我的布局。例如:
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
<timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>true</prettyPrint>
</jsonFormatter>
</layout>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
导致消息以 JSON 和纯文本格式记录。
我确实可以将这 3 个文件的内容复制并粘贴到我的自定义配置中,而不是完全导入它们。然后我可以覆盖我想要自定义的内容。
但是,随着春季的发展和可能添加功能的新版本的发布,我将永远强迫自己跟上、复制和粘贴新文件并进行更改并测试它们。
有没有更好的方法可以:
- 只需对附加器进行附加更改,而不是完全重新定义它们,例如保持配置不受弹簧影响,但提供我自己的编码器或布局以供这些附加器使用。
- 完全通过属性将 spring 配置为 JSON 日志而无需任何配置 - 我对此表示怀疑:S
脚注:logzio 确实提供了一个可以导入的依赖项,但我不喜欢将日志记录提供程序直接耦合到代码中的想法。我觉得如果伺服器恰好将 JSON 日志生成到标准输出或文件,那么任何提供商都可以轻松处理这些日志并将它们发送到某个目的地。