Spring Boot使用Logback

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";
    }
}

讓我們爲應用程序添加一個具有日誌代碼的 SpringLoggingHelper 類。儘管此類除了發出日誌記錄語句之外什麼都不做, 但它將幫助我們瞭解如何在不同的包中配置日誌記錄。代碼如下:
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");
 
    }
}
在上面的兩個類中, 我們編寫了針對 SLF4J API 的日誌記錄代碼。SLF4J 是通常使用的日誌框架的門面, 例如 Java .Util.Logging、Log4J 2 和 Logback。通過對SLF4J的編寫,我們的代碼仍然與Logback分離,從而爲我們提供了在不同的日誌框架中切換的靈活性,如果以後需要的話修改其他日誌框架,是很方便的
如果您想知道 SLF4J 和 Logback 依賴關係的話, 這將不需要指定任何內容。Spring Boot也包含它們。假設您使用 Maven 或 Gradle 管理 spring boot項目, 則必要的依賴項是 spring boot下的依賴項的一部分。運行 SpringBootWebApplication 主類。當應用程序啓動時,使用 URL從瀏覽器訪問http://localhost:8080,IntelliJ控制檯上的日誌記錄輸出爲:

我們還沒有爲 Logback 寫任何配置。IndexController 和 SpringLoggingHelper 類的輸出都來自 logback 根記錄器。請注意, DEBUG消息未被記錄。默認情況下, Logback 將記錄DEBUG級別消息。但是, spring boot團隊爲我們提供了在 spring 啓動默認 Logback 配置文件 (base.xml) 。此外, Spring boot提供了兩個預配置的附加目的地通過console-appender. xml 和文件file-appender.xml。base.xml 文件引用它們。

以下是從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>
在這裏, 您可以看到 Spring boot已通過將根記錄器設置爲INFO來覆蓋 Logback 的默認日誌記錄級別, 這是我們在上面的示例中沒有看到調試消息的原因。正如我們在下一節中看到的, 在 Spring boot中更改日誌級別非常簡單

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 日誌級別等。還可以定義一個日誌文件, 以將日誌消息寫入到控制檯之外。
下面是application.properties文件的日誌配置
logging.level.org.springframework.web=INFO
logging.level.guru.springframework.controllers=DEBUG
logging.level.org.hibernate=ERROR
logging.file=logs/spring-boot-logging.log
注意: 還有一個logging.path 屬性, 用於指定記錄文件的路徑。如果使用它, Spring boot會在指定路徑中創建一個 spring.log 文件。但是, 不能同時指定logging.file和logging.path屬性。如果同時配置,Spring Boot將全部忽略。
當您現在運行main 類並訪問應用程序時, 從 IndexController 和 SpringLoggingHelper 的日誌消息將記錄到控制檯和logs/spring-boot-logging.log文件。

在輸出中, 請注意, IndexController 的DEBUG和更高級別的消息被記錄到控制檯和文件中。這是因爲在application.properties文件中, 我們指定了DEBUG作爲 guru.springframework.controllers 包的日誌級別, IndexController 是其中的一部分。由於我們沒有顯式配置 SpringLoggingHelper 類, 所以使用了base.xml 文件的默認配置。因此, 僅記錄了 SpringLoggingHelper 的信息和更高級別的消息。


當需要爲特定類或包獲取更詳細的日誌消息時, 可以看到這是多麼簡單。

Logback Configuration through an External File

Logback通過application.properties文件對於許多 Spring boot應用程序來說都是足夠的。但是, 大型企業應用程序可能具有更復雜的日誌記錄要求。正如我前面提到的, Logback 通過 XML 和 Groovy 配置文件支持高級日誌記錄配置。

在 Spring boot應用程序中, 可以在項目類路徑中指定Logback配置文件 logback.xml或 logback-spring.xml。不過, spring boot團隊建議使用 spring 變體來進行日誌配置, logback-spring. xml 比 logback xml 更可取。如果使用標準 logback 配置, 則 Spring boot可能無法完全控制日誌初始化。

下面是 logback-spring.xml文件的代碼。
<?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>
在上面的配置代碼中, 我們將base.xml文件在第三行引入, 注意到我們沒有配置任何appenders。相反, 我們依賴於CONSOLE和FILE, 這些都是由 Spring boot提供的。

通過更新 Spring boot Logback 配置, 我們日誌輸出現在看起來這樣:

注意: spring boot期望 logback-spring.xml的配置文件放在類路徑上。但是, 可以存儲其他位置, 並使用應用程序application.properties文件中指定logging.config屬性改變它
注意:如果logback-spring.xml放在Spring boot resources目錄,寫法如下
       logging.config=classpath:logback-spring.xml

Spring Boot Profiles in Logging

在本地計算機中開發時, 通常要將日誌級別設置爲 "DEBUG"。這將爲您的開發使用提供詳細的日誌消息。在生產時, 其典型設置爲WARN或以上的日誌級別。這是爲了避免在生產中運行時使用過多的調試信息和記錄開銷來填充日誌。雖然日誌記錄非常有效, 但仍有成本。

spring boot通過將 logback 配置的 spring 配置文件擴展到 <springProfile> 元素來滿足這些要求。在 logback 文件中使用此元素, 可以根據活動的 spring 配置文件選擇包含或排除日誌配置。

注意: 對 <springProfile> logback 配置的支持可從SpringBoot 1.3.0.M2里程碑開始。

下面是一個 XML 示例, 用於使用活動的 Spring 配置文件配置 Logback。
<?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 參數, 如下所列。

現在, 我們使用dev配置文件運行應用程序, 我們看到以下日誌輸出


在上述輸出中, 觀察 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>
完整的logback-spring.xml文件如下:
<?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

在 logback-spring.xml文件中, 可以通過設置scan="true" 屬性啓用對配置的自動掃描。啓用自動掃描後, Logback 掃描配置文件中的更改。對於任何更改, Logback 會自動使用它們進行重新配置。通過將時間段傳遞給 scanPeriod 屬性, 可以指定掃描期間, 並以毫秒、秒、分鐘或小時爲單位指定值。
例如, 此代碼告訴 Logback 在每10秒後掃描 Logback-spring. xml。
<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

Logback 在開源社區中的流行趨勢。許多流行的開源項目使用 Logback 來滿足他們的日誌需求。Apache Camel, Gradle只是幾個例子。

Logback 顯然具有處理複雜企業應用程序中的日誌記錄需求的能力。所以, 難怪Spring boot 團隊爲默認的日誌記錄實現選擇 Logback。正如您在這篇文章中看到的, Spring boot 團隊提供了與 Logback 的良好集成。出框, Logback 準備使用Spring boot。篇文章, 已經看到了在日誌要求不斷變化的情況 Spring boot配置 Logback 多麼容易


翻譯自: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>


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章