USING LOGBACK WITH SPRING BOOT
Logback 爲企業應用程序製作了一個優秀的日誌框架-它的速度快, 具有簡單但功能強大的配置選項, 而且內存佔用小。在我的入門帖子中已經介紹了 logback , logback 介紹: 企業日誌框架。在 Logback 的一系列帖子中, 我還討論瞭如何使用 XML 和 Groovy 配置 Logback。這些帖子可用作 Logback 配置: 使用 XML 和 Logback 配置: 使用 Groovy。
在這篇文章中, 我將討論在Spring Boot中如何使用 Logback。雖然 Java 有許多日誌框架選項, 但 Spring boot選擇了使用 Logback 作爲默認記錄器。像Spring boot 裏的許多東西一樣, 默認情況下, Logback 會使用合理的默認值進行配置。開箱即用, Spring Boot 使 Logback 易於使用。
Creating Loggers
在上一個帖子中, 我寫了有關使用 Spring boot創建 web 應用程序的內容。我們將爲這個應用程序配置 logback。該應用程序包含一個控制器, 加日誌代碼到IndexController控制器。IndexController的最終代碼如下:
package guru.springframework.controllers;
import guru.springframework.helpers.SpringLoggingHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping("/")
String index(){
logger.debug("This is a debug message");
logger.info("This is an info message");
logger.warn("This is a warn message");
logger.error("This is an error message");
new SpringLoggingHelper().helpMethod();
return "index";
}
}
package guru.springframework.helpers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SpringLoggingHelper {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public void helpMethod(){
logger.debug("This is a debug message");
logger.info("This is an info message");
logger.warn("This is a warn message");
logger.error("This is an error message");
}
}
以下是從git上找到spring-boot用的base.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Base logback configuration provided for compatibility with Spring Boot 1.1
-->
<included>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</included>
Configuration via Spring Boot’s application.properties File
在 Spring boot應用程序中, 可以將配置具體化爲在不同環境中使用相同的應用程序代碼。application.properties文件很可能是幾種不同的方式來外部化 Spring boot配置屬性的最流行的方法。在 Spring boot web 應用程序的默認結構中, 可以在 "Resources" 文件夾下定位application.properties文件。在application.properties文件中, 可以定義 Spring boot日誌級別、應用日誌日誌級別、Hibernate日誌級別、Thymeleaf 日誌級別等。還可以定義一個日誌文件, 以將日誌消息寫入到控制檯之外。logging.level.org.springframework.web=INFO
logging.level.guru.springframework.controllers=DEBUG
logging.level.org.hibernate=ERROR
logging.file=logs/spring-boot-logging.log
在輸出中, 請注意, IndexController 的DEBUG和更高級別的消息被記錄到控制檯和文件中。這是因爲在application.properties文件中, 我們指定了DEBUG作爲 guru.springframework.controllers 包的日誌級別, IndexController 是其中的一部分。由於我們沒有顯式配置 SpringLoggingHelper 類, 所以使用了base.xml 文件的默認配置。因此, 僅記錄了 SpringLoggingHelper 的信息和更高級別的消息。
當需要爲特定類或包獲取更詳細的日誌消息時, 可以看到這是多麼簡單。
Logback Configuration through an External File
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="guru.springframework.controllers" level="WARN" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</logger>
<logger name="guru.springframework.helpers" level="WARN" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</logger>
</configuration>
logging.config=classpath:logback-spring.xml
Spring Boot Profiles in Logging
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<springProfile name="dev,staging">
<logger name="guru.springframework.controllers" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>>
</springProfile>
<springProfile name="production">
<logger name="guru.springframework.controllers" level="WARN" additivity="false">
<appender-ref ref="FILE" />
</logger>
</springProfile>
</configuration>
在上面的配置代碼中, 對於dev和staging profiles, 我們配置了 guru.springframework.controllers 記錄器, 以便將DEBUG和更高級別的消息記錄到控制檯。對於生產配置文件, 我們配置了相同的記錄器, 以便將警告和更高級別的消息記錄到文件中。若要將配置文件傳遞給應用程序, 請使用 -Dspring.profiles.active= JVM 參數運行應用程序。
對於本地開發, 在 IntelliJ 中, 選擇 "運行-編輯配置", 然後在 "運行/調試配置" 對話框中設置 JVM 參數, 如下所列。
在上述輸出中, 觀察 IndexController 的測井輸出。根據dev文件的配置, 調試和更高的日誌消息被記錄到控制檯。您可以使用production文件重新啓動應用程序, 以確保將警告和更高的日誌消息記錄到文件中。
Conditional Processing of Configuration File
Logback 支持在 Janino 庫的幫助下對配置文件進行條件處理。可以使用配置文件中的 <if>、<then> 和 <else> 元素來針對多個環境。要執行條件處理, 請將 Janino 依賴項添加到您的 Maven POM, 如下所願。
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>2.7.8</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<springProfile name="dev,staging">
<logger name="guru.springframework.controllers" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>>
</springProfile>
<springProfile name="production">
<logger name="guru.springframework.controllers" level="WARN" additivity="false">
<appender-ref ref="FILE" />
</logger>
</springProfile>
<if condition='property("spring.profiles.active").contains("dev")'>
<then>
<logger name="guru.springframework.helpers" level="DEBUG" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
</then>
<else>
<logger name="guru.springframework.helpers" level="WARN" additivity="false">
<appender-ref ref="FILE" />
</logger>
</else>
</if>
</configuration>
在上面的代碼中, 我們在 <if> 元素中指定了一個條件, 以檢查當前active profile 是否包dev。如果條件計算結果爲 true, 則 <then> 元素內的配置代碼將執行。在 <then> 元素中, 我們配置 guru.springframework.helpers 將DEBUG和更高的消息記錄到控制檯。我們使用 <else> 元素來配置記錄器, 以便將WARN和更高的消息記錄到日誌文件中。<else> 元素爲dev以外的任何配置文件執行。當您使用生產配置文件運行應用程序並對其進行訪問時, 兩個記錄器都會將警告和更高的消息記錄到日誌文件中, 類似於此。
對於開發人員配置文件, 兩個記錄器都會將調試和更高的消息記錄到控制檯, 類似於此。
Logback Auto-Scan Issue with Spring Boot
<configuration debug="true" scan="true" scanPeriod="10 seconds" >
...
</configuration>
Spring boot Logback 的一個限制是, 使用 springProfile 和 springProperty, 設置自動掃描會導致錯誤。
//Error on using auto-scan with springProfile
-ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:39 - no applicable action for [springProfile],
current ElementPath is [[configuration][springProfile]]
//Error on using auto-scan with springProperty
-ERROR in ch.qos.logback.core.joran.spi.Interpreter@12:125 - no applicable action for [springProperty],
current ElementPath is [[configuration][springProperty]]
錯誤是由於不兼容問題而發生的。Spring boot使用 JoranConfigurator 子類支持 springProfile 和 springProperty。不幸的是, Logback 的 ReconfigureOnChangeTask 並沒有提供一個鉤子插入它。
Conclusion
翻譯自:https://springframework.guru/using-logback-spring-boot/
我現在用的配置方式(每天晚上對當天log進行壓縮存儲,一天一個壓縮包)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%t] [%C#%M:%L] - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${root}/logs/stream-collector-%d{yyyyMMdd}.log.zip</fileNamePattern>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%t] [%C#%M:%L] - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>