Logback - 布局& logback.xml中的模式

时间:2017-10-04 09:02:10

标签: spring-boot logback

我正在使用slf4j的logback来登录Spring Boot应用程序。我创建了一个自定义布局类,因为所有日志语句都包装为json。我已经将logback-spring.xml配置为如下所示,以获取自定义布局。有用!

问题是我无法应用模式。只有布局工作(或)模式。我想要的总是在日志上,转到布局类,然后在记录之前应用模式。

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${user.home}/logs/sample.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>${user.home}/logs/sample_%d{yyyy-MM-dd}.%i.log</fileNamePattern>

        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
        <!-- how many days to keep the files -->
        <maxHistory>30</maxHistory>
    </rollingPolicy>

    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="com.test.test.payment.core.logging.SampleLogLayout" >
        </layout>
    </encoder>
    *<!-- <encoder>
        <charset>UTF-8</charset>
        <Pattern>{"@timestamp": "%d{yyyy-MM-dd HH:mm:ss.SSS}", "priority": "%p", "application": "payment",
            "class": "%C", "file": "%F:%L", "payload": %m }%n
        </Pattern>
    </encoder>-->*
</appender>

这是SampleLogLayout班级:

public class SampleLogLayout extends LayoutBase<LoggingEvent> {

    @Override
    public String doLayout(LoggingEvent event) {

        String renderedMessage = event.getMessage();

        if (!isJson(renderedMessage)) {
            Throwable throwable = null;

            if (event.getLevel().equals(Level.ERROR) || event.getLevel().equals(Level.WARN)) {

            final IThrowableProxy throwableProxy = event.getThrowableProxy();
            if ((throwableProxy != null) && (throwableProxy instanceof ThrowableProxy)) {
                ThrowableProxy proxy = (ThrowableProxy) throwableProxy;
                throwable = proxy.getThrowable();
            }
            String message = LogErrorMessage.create(CommonCoreErrors.GENERIC_ERROR)
                    .message(renderedMessage).exception(throwable).build();

            return message;
        } else {
                return LogMessage.create(renderedMessage).build();
        }

        }
        return renderedMessage;
    }

    private boolean isJson(String msg) {
        if (null == msg) {
            return false;
        } else {
            return msg.startsWith("{") && msg.endsWith("}");
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我开始重现这一点,以便提供完整的解决方案,但缺少LogMessageLogErrorMessage使得这有点棘手。

但是,在我看来,您只想登录JSON格式,而不仅仅是消息,还有timestamppriority等元数据。

这可以通过使用JsonLayout来实现。以下是布局配置的示例:

<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>
    <includeContextName>false</includeContextName>
</layout>

使用该配置进行以下日志调用...

logger.info("{\"a\": 1, \"b\": 2}");

...将发出:

{"timestamp":"2017-10-05 10:51:34.610","level":"INFO","thread":"main","logger":"com.stackoverflow.logback.LogbackTest","message":"{\"a\": 1, \"b\": 2}"} 

您也可以包含MDC,例如......

MDC.put("application", "payment");
logger.info("{\"a\": 1, \"b\": 2}");

...将发出:

{"timestamp":"2017-10-05 10:52:56.088","level":"INFO","thread":"main","mdc":{"application":"payment"},"logger":"com.stackoverflow.logback.LogbackTest","message":"{\"a\": 1, \"b\": 2}"}

这非常接近您想要的输出,JsonLayout是可扩展的,所以你可以......

  • 覆盖toJsonMap()以更改密钥的名称,例如将timestamp替换为@timestamp,将message替换为payload
  • 实施addCustomDataToJsonMap()以将其他键:值对添加到日志事件

因此,我认为您可以使用预先存在的JsonLayout来实现所需的输出,而不是自己编写。

有关Logback JSON扩展here的详细信息。

Maven坐标是:

<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-json-core</artifactId>
    <version>0.1.5</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback.contrib</groupId>
    <artifactId>logback-jackson</artifactId>
    <version>0.1.5</version>
</dependency>