slf4j + log4j2 的使用

前言

log4j2log4j 的進化版本,並提供了許多 logback 可用的改進,同時解決了 Logback 體系結構中的一些固有問題。本文將從slf4j+log4j2的快速使用開始,然後介紹log4j2的優異性能以及log4j2配置文件相關的詳細說明。

log4j2 官網文檔:https://logging.apache.org/log4j/2.x/

快速使用

引入依賴

  • 如果是SpringBoot項目,可以引入下面的依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
  • 如果是普通的Maven項目則需引入如下依賴
<properties>
    <log4j2.version>2.13.3</log4j2.version>
</properties>

<!-- 日誌框架 slf4j+log4j2-->
<!-- slf4j依賴 -->
<dependencies>
	<dependency>
	    <groupId>org.slf4j</groupId>
	    <artifactId>slf4j-api</artifactId>
	    <version>1.7.30</version>
	</dependency>
	<!-- log4j2和slf4j橋接依賴-->
	<dependency>
	    <groupId>org.apache.logging.log4j</groupId>
	    <artifactId>log4j-slf4j-impl</artifactId>
	    <version>${log4j2.version}</version>
	    <scope>test</scope>
	</dependency>
	<!-- log4j2依賴-->
	<dependency>
	    <groupId>org.apache.logging.log4j</groupId>
	    <artifactId>log4j-api</artifactId>
	    <version>${log4j2.version}</version>
	</dependency>
	<dependency>
	    <groupId>org.apache.logging.log4j</groupId>
	    <artifactId>log4j-core</artifactId>
	    <version>${log4j2.version}</version>
	</dependency>
</dependencies>

排除依賴衝突

Spring Boot 2.x默認使用Logback日誌框架,要使用 log4j2必須先排除 logback
例子

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
         <!--排除logback-->
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

如果還有其他的依賴衝突,看控制檯報錯信息和pom.xml文件的依賴圖(右鍵點擊Show Dependencies…), 進行排除(Exclude), 依賴圖裏面有紅線的,就是存在依賴衝突的,但運行不一定會報錯,報錯的衝突是一定要解決的。排除後,需要進行 Reimport 重新導入依賴

依賴圖裏查找依賴的方法
快捷鍵 ctrl+F,彈出圖元素框後,雖然沒有搜索框,但是可以繼續輸入查找的內容,輸入之後,查找的內容就會出現了,如下圖所示。

在這裏插入圖片描述

配置文件

log4j2 配置文件名稱和加載順序

使用log4j2之前需要在classpath下新建一個配置文件。如果沒有任何配置,log4j2將使用缺省配置。需要注意的是 log4j 2.x 版本不再支持像 1.x 中的.properties後綴的文件配置方式,2.x 版本配置文件後綴名只能爲".xml",".json“或者”.jsn"。

系統選擇配置文件的優先級(從先到後)如下:

classpath下的名爲log4j2-test.json 或者log4j2-test.jsn的文件
classpath下的名爲log4j2-test.xml的文件
classpath下名爲log4j2.json 或者log4j2.jsn的文件
classpath下名爲log4j2.xml的文件

我們一般默認使用log4j2.xml進行命名。如果本地要測試,可以把log4j2-test.xml放到classpath,而正式環境使用log4j2.xml,則在打包部署的時候不要打包log4j2-test.xml即可。
  
log4j2配置文件的位置

默認情況下,只要把log4j2配置文件放在 classpath 環境變量所指定的目錄即可,即IDEA中的resources根目錄下(不是它裏面的子文件夾)。如果想放在其他位置,比如resources/config文件夾下,則需要在application.yml增加自定義的配置:

# 日誌
logging:
  config: classpath:config/log4j2.xml

配置文件例子

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="debug" monitorInterval="30">
    <!-- 先定義所有的appender(附加器)-->
    <appenders>
        <!-- 輸出控制檯的配置 -->
        <Console name="Console" target="SYSTEM_OUT">
            <!-- 控制檯只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch) -->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <!-- 輸出日誌的格式 -->
            <PatternLayout pattern="[%d{HH:mm:ss.SSS}] [%-5p] %l - %m%n"/>
        </Console>

        <!-- 文件會打印出所有信息,這個log每次運行程序會自動清空,由append屬性決定,這個也挺有用的,適合臨時測試用 -->
        <!-- append爲TRUE表示消息增加到指定文件中,false表示消息覆蓋指定的文件內容,默認值是true -->
        <File name="log" fileName="log/test.log" append="false">
            <PatternLayout pattern="[%d{HH:mm:ss.SSS}] [%-5p] %l - %m%n"/>
        </File>

        <!-- 添加過濾器ThresholdFilter,可以有選擇的輸出某個級別以上的類別  onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否則直接拒絕  -->
        <File name="ERROR" fileName="logs/error.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="[%d{yyyy.MM.dd 'at' HH:mm:ss z}] [%-5p] %l - %m%n"/>
        </File>

        <!-- 這個會打印出所有的信息,每次大小超過size,則這size大小的日誌會自動存入按年份-月份建立的文件夾下面並進行壓縮,作爲存檔 -->
        <RollingFile name="RollingFile" fileName="logs/web.log"
                     filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz">
            <PatternLayout pattern="[%d{yyyy-MM-dd 'at' HH:mm:ss z}] [%-5p] %l - %m%n"/>
            <SizeBasedTriggeringPolicy size="2MB"/>
        </RollingFile>
    </appenders>

    <!-- 然後定義logger,只有定義了logger並引入的appender,appender纔會生效 -->
    <loggers>
        <!-- 過濾掉spring和mybatis的一些無用的DEBUG信息-->
        <logger name="org.springframework" level="INFO"></logger>
        <logger name="org.mybatis" level="INFO"></logger>
        <!-- 建立一個默認的root的logger -->
        <root level="trace">
            <appender-ref ref="RollingFile"/>
            <appender-ref ref="Console"/>
            <appender-ref ref="ERROR"/>
            <appender-ref ref="log"/>
        </root>
    </loggers>

</configuration>

日誌打印代碼

使用lombok插件中的@Slf4j 註解可以很方便的使用 org.slf4j.Logger 對象。日常開發儘量使用Slf4j門面來處理日誌,儘量避免使用具體的日誌框架

@Slf4j
@SpringBootTest
public class LogTests {

    @Test
    public void m1() {
        log.trace("trace");
        log.debug("debug");
        log.info("info");
        log.warn("warn");
        log.error("error");
        log.error("error {}", "param");
    }
}

控制檯輸出:

[17:54:58.712] [INFO ] com.chenqunhui.blog.LogTests.m1(LogTests.java:20) - info
[17:54:58.712] [WARN ] com.chenqunhui.blog.LogTests.m1(LogTests.java:21) - warn
[17:54:58.712] [ERROR] com.chenqunhui.blog.LogTests.m1(LogTests.java:22) - error
[17:54:58.713] [ERROR] com.chenqunhui.blog.LogTests.m1(LogTests.java:23) - error param

log4j2的優點

市面上的日誌框架多種多樣:log4jlog4j2slf4jJDKLoglogback等等。log4j目前已經停止更新了。Apache推出了新的log4j2來代替log4jlog4j2是對log4j的升級,與其前身log4j相比有了顯着的改進,並提供了許多logback可用的改進,同時解決了logback體系結構中的一些固有問題。因此,log4j2 + slf4j應該是未來的大勢所趨。

log4j2的性能
log4j2最牛逼的地方在於異步輸出日誌時的性能表現,log4j2在多線程的環境下吞吐量與log4jlogback的比較如下圖。下圖比較中log4j2有三種模式:
1)全局使用異步模式;
2)部分Logger採用異步模式;
3)異步Appender。
可以看出在前兩種模式下,log4j2的性能較之log4jlogback有很大的優勢。
在這裏插入圖片描述
完整的官方性能文檔:https://logging.apache.org/log4j/2.x/performance.html

log4j2.xml配置文件說明

<configuration status="debug" monitorInterval="30">

  1. 根節點Configuration有兩個屬性: statusmonitorinterval, 兩個子節點:AppendersLoggers(表明可以定義多個AppenderLogger)。

    其中,status用來指定log4j本身的打印日誌的級別。
    monitorinterval用於指定log4j自動重新配置的監測間隔時間, 是用來設置配置文件的動態加載時間的,單位是s, 最小是5s。monitorInterval="30"表示每30秒配置文件會動態加載一次。在程序運行過程中,如果修改配置文件,程序會隨之改變。

  2. Appenders節點,常見的有三種子節點:ConsoleRollingFileFile

    Console節點用來定義輸出到控制檯的Appender
     (1) name:指定Appender的名字.
     (2) target:SYSTEM_OUTSYSTEM_ERR,一般只設置默認:SYSTEM_OUT.
     (3) PatternLayout:輸出格式,不設置默認爲:%m%n.

    File節點用來定義輸出到指定位置的文件的Appender.
     (1)name:指定Appender的名字.
     (2)fileName:指定輸出日誌的目的文件帶全路徑的文件名.
     (3)PatternLayout:輸出格式,不設置默認爲: %m%n.

    RollingFile節點用來定義日誌文件超過指定大小自動刪除舊的創建新的的Appender.
    自動追加日誌信息到文件中,直至文件達到預定的大小,然後自動重新生成另外一個文件來記錄之後的日誌。
     (1)name:指定Appender的名字.
     (2)fileName:指定輸出日誌的目的文件帶全路徑的文件名.
     (3)PatternLayout:輸出格式,不設置默認爲:%m%n.
     (4)filePattern:指定新建日誌文件的名稱格式.
     (5)Policies:指定滾動日誌的策略,就是什麼時候進行新建日誌文件輸出日誌.
     (6)TimeBasedTriggeringPolicy: Policies子節點,基於時間的滾動策略,interval屬性用來指定多久滾動一次,默認是1hour。modulate=true用來調整時間:比如現在是早上3am,interval是4,那麼第一次滾動是在4am,接着是8am,12am…而不是7am.
     (7)SizeBasedTriggeringPolicy:Policies子節點,基於指定文件大小的滾動策略,size屬性用來定義每個日誌文件的大小.
     (8)DefaultRolloverStrategy:用來指定同一個文件夾下最多有幾個日誌文件時開始刪除最舊的,創建新的(通過max屬性)。

  3. Loggers節點,常見的有兩種子節點:RootLogger.

    Root節點用來指定項目的根日誌,如果沒有單獨指定Logger,那麼就會默認使用該Root日誌輸出
      ○ level:日誌輸出級別,共有8個級別,按照從低到高爲:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
      ○ appender-refRoot的子節點,用來指定該日誌輸出到哪個Appender.

    Logger節點用來單獨指定日誌的形式,比如要爲指定包下的class指定不同的日誌級別等。
      ○ level:日誌輸出級別,共有8個級別,按照從低到高爲:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
      ○ name:用來指定該Logger所適用的類或者類所在的包全路徑,繼承自Root節點.
      ○ appender-refLogger的子節點,用來指定該日誌輸出到哪個Appender,如果沒有指定,就會默認繼承自Root.如果指定了,那麼會在指定的這個AppenderRootAppender中都會輸出,此時我們可以設置Loggeradditivity="false"只在自定義的Appender中進行輸出。

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