2017-10-04 67 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