2017-10-04 69 views
1

我使用logback和slf4j登录Spring Boot应用程序。我创建了一个自定义的布局类,因为所有的日志语句都被包装为一个json。我已经配置了如下所示的logback-spring.xml以采用自定义布局。有用!Logback - logback.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("}"); 
     } 
    } 
} 
+0

我认为,我们需要看到这个类太:'com.test.test.payment.core.logging.SampleLogLayout' – glytching

+0

是的,增加了我的SampleLogLayout类。基本上LogErrorMessage.create()和LogMessage.create()将消息转换为JSON – deejo

+0

好的,这很有用。我仍然不清楚问题是什么。你是说你想'SampleLogLayout'发出带有模式的'renderedMessage'?也许增加(1)一个示例日志调用(以便我们可以看到'renderedMessage'看起来像什么)和(2)期望的输出将有助于澄清事情。 – glytching

回答

0

我开始重现此,以提供一个完整的解决方案,但由于缺乏LogMessageLogErrorMessage作出有点棘手。

但是,它看起来像你对我只是想登录JSON格式,不只是信息,但也priority

这可以通过使用JsonLayout来实现的元数据,如timestamp。这里的布局配置的例子:

<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实施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> 
+0

Thanks glitch!有用。我尝试过使用,并且使用JsonFormatLogConverter扩展了ClassicConverter。我会去解决你的问题。谢谢 – deejo