天天看點

java日志大全-第5篇:Log4j2

作者:不開心就撸代碼

一、log4j2的使用

Apache Log4j 2是對Log4j的更新版,參考了logback的一些優秀的設計,并且修複了一些問題,是以帶來了一些重大的提升,主要有:

l 異常處理,在logback中,Appender中的異常不會被應用感覺到,但是在log4j2中,提供了一些異常處理機制。

l 性能提升, log4j2相較于log4j 和logback都具有很明顯的性能提升,後面會有官方測試的資料。

l 自動重載配置,參考了logback的設計,當然會提供自動重新整理參數配置,最實用的就是我們在生産上可以動态的修改日志的級别而不需要重新開機應用。

l 無垃圾機制,log4j2在大部分情況下,都可以使用其設計的一套無垃圾機制,避免頻繁的日志收集導緻的jvm gc。

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

1. Log4j2入門

目前市面上最主流的日志門面就是SLF4J,雖然Log4j2也是日志門面,因為它的日志實作功能非常強大,性能優越。是以大家一般還是将Log4j2看作是日志的實作,Slf4j + Log4j2應該是未來的大勢所趨。

Ø 添加依賴

<!-- Log4j2 門面API-->
<dependency>
 <groupId>org.apache.logging.log4j</groupId>
 <artifactId>log4j-api</artifactId>
 <version>2.11.1</version>
</dependency>
<!-- Log4j2 日志實作 -->
<dependency>
 <groupId>org.apache.logging.log4j</groupId>
 <artifactId>log4j-core</artifactId>
 <version>2.11.1</version>
</dependency>           

Ø 代碼

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;

public class Demo1 {

 private static final Logger LOGGER = LogManager.getLogger(Demo1.class);

   @Test
   public void test1(){
     LOGGER.fatal("fatal");
     LOGGER.error("error"); //預設error級别
     LOGGER.warn("warn");
     LOGGER.info("info");
     LOGGER.debug("debug");
     LOGGER.trace("trace");
   }
}           
輸出:
java日志大全-第5篇:Log4j2

2. 使用slf4j作為日志的門面,使用log4j2作為日志的實作

Ø 添加依賴

<!-- Log4j2 門面API-->
<dependency>
 <groupId>org.apache.logging.log4j</groupId>
 <artifactId>log4j-api</artifactId>
 <version>2.11.1</version>
</dependency>
<!-- Log4j2 日志實作 -->
<dependency>
 <groupId>org.apache.logging.log4j</groupId>
 <artifactId>log4j-core</artifactId>
 <version>2.11.1</version>
</dependency>

<!--使用slf4j作為日志的門面,使用log4j2來記錄日志 -->
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <version>1.7.25</version>
</dependency>
<!--為slf4j綁定日志實作 log4j2的擴充卡 -->
<dependency>
 <groupId>org.apache.logging.log4j</groupId>
 <artifactId>log4j-slf4j-impl</artifactId>
 <version>2.10.0</version>
</dependency>           

配置檔案:

<?xml version="1.0" encoding="UTF-8"?>
<!--
 status="warn" 日志架構本身的輸出日志級别
 monitorInterval="5" 自動加載配置檔案的間隔時間,不低于 5 秒
-->
<Configuration status="debug" monitorInterval="5">
 <!-- 配置集中管理的屬性 通過 ${name} 進行引用 -->
 <properties>
 <!--日志輸出的位置-->
 <property name="log_home">d://logs</property>
 <!--輸出的格式-->
 <property name="pattern">%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n</property>
 </properties>

 <!--日志處理-->
 <Appenders>
 <!--控制台輸出-->
 <Console name="Console" target="SYSTEM_ERR">
 <!--輸出的格式-->
 <PatternLayout pattern="${pattern}" />
 </Console>

 <!--檔案輸出-->
 <File name="File" fileName="${log_home}/fileLog.log">
 <PatternLayout pattern="${pattern}" />
 </File>

 <!--使用随機讀寫流日志檔案輸出 appender,性能提高-->
 <RandomAccessFile name="accessFile" fileName="${log_home}/accessLog.log">
 <PatternLayout pattern="${pattern}" />
 </RandomAccessFile>

 <!--按照一定規則拆分的日志檔案-->
 <RollingFile name="rollingFile" fileName="${log_home}/rollLog.log"
 filePattern="${log_home}/${date:yyyy-MM-dd}/myrollog-%d{yyyy-MM-dd-HH-mm}-%i.log">
 <!--日志級别過濾器-->
 <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" />
 <!--日志消息格式-->
 <PatternLayout pattern="${pattern}" />
 <Policies>
 <!--在系統啟動時,出發拆分規則,生産一個新的日志檔案-->
 <OnStartupTriggeringPolicy />
 <!--按照檔案大小拆分,10MB -->
 <SizeBasedTriggeringPolicy size="1MB" />
 <!--按照時間節點拆分,規則根據filePattern定義的-->
 <TimeBasedTriggeringPolicy />
 </Policies>
 <!--在同一個目錄下,檔案的個數限定為 30 個,超過進行覆寫-->
 <DefaultRolloverStrategy max="30" />
 </RollingFile>
 </Appenders>

 <!--logger定義-->
 <Loggers>
 <Root level="trace">
 <!--指定日志使用的處理器-->
 <AppenderRef ref="Console" />
 <AppenderRef ref="rollingFile" />
<!-- <AppenderRef ref="File" />-->
<!-- <AppenderRef ref="accessFile" />-->
 </Root>
 </Loggers>
</Configuration>           

3. 異步日志

Log4j2提供了兩種實作日志的方式,一個是通過AsyncAppender,一個是通過AsyncLogger,分别對應前面我們說的Appender元件和Logger元件。

Ø 依賴

<!--異步日志依賴-->
<dependency>
 <groupId>com.lmax</groupId>
 <artifactId>disruptor</artifactId>
 <version>3.3.4</version>
</dependency>           

Ø 配置檔案:Appender元件方式

<?xml version="1.0" encoding="UTF-8"?>
<!--
 status="warn" 日志架構本身的輸出日志級别
 monitorInterval="5" 自動加載配置檔案的間隔時間,不低于 5 秒
-->
<Configuration status="debug" monitorInterval="5">
 <!-- 配置集中管理的屬性 通過 ${name} 進行引用 -->
 <properties>
 <!--日志輸出的位置-->
 <property name="log_home">d://logs</property>
 <!--輸出的格式-->
 <property name="pattern">%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n</property>
 </properties>

 <!--日志處理-->
 <Appenders>
 <!--控制台輸出-->
 <Console name="Console" target="SYSTEM_ERR">
 <!--輸出的格式-->
 <PatternLayout pattern="${pattern}" />
 </Console>

 <!--檔案輸出-->
 <File name="File" fileName="${log_home}/fileLog.log">
 <PatternLayout pattern="${pattern}" />
 </File>

 <Async name="async">
 <AppenderRef ref="File"/>
 </Async>
 </Appenders>

 <!--logger定義-->
 <Loggers>
 <Root level="trace">
 <!--指定日志使用的處理器-->
 <AppenderRef ref="Console" />
 <AppenderRef ref="async" />
 </Root>
 </Loggers>
</Configuration>           

Ø 配置檔案:AsyncLogger元件方式

AsyncLogger才是log4j2 的重頭戲,也是官方推薦的異步方式。它可以使得調用Logger.log傳回的更快。你可以有兩種選擇:全局異步和混合異步。

² 全局異步就是,所有的日志都異步的記錄,在配置檔案上不用做任何改動,隻需要添加一個 log4j2.component.properties 配置;

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector           

² 混合異步就是,你可以在應用中同時使用同步日志和異步日志,這使得日志的配置方式更加靈活。

<?xml version="1.0" encoding="UTF-8"?>
<!--
 status="warn" 日志架構本身的輸出日志級别
 monitorInterval="5" 自動加載配置檔案的間隔時間,不低于 5 秒
-->
<Configuration status="debug" monitorInterval="5">
 <!-- 配置集中管理的屬性 通過 ${name} 進行引用 -->
 <properties>
 <!--日志輸出的位置-->
 <property name="log_home">d://logs</property>
 <!--輸出的格式-->
 <property name="pattern">%d{HH:mm:ss.SSS} [%t] [%-5level] %c{36}:%L --- %m%n</property>
 </properties>

 <!--日志處理-->
 <Appenders>
 <!--控制台輸出-->
 <Console name="Console" target="SYSTEM_ERR">
 <!--輸出的格式-->
 <PatternLayout pattern="${pattern}" />
 </Console>

 <!--檔案輸出-->
 <File name="File" fileName="${log_home}/fileLog.log">
 <PatternLayout pattern="${pattern}" />
 </File>

 <Async name="async">
 <AppenderRef ref="File"/>
 </Async>
 </Appenders>

 <!--logger定義-->
 <Loggers>
 <!--自定義異步 logger 對象
 includeLocation="false" 關閉日志記錄的行号資訊
 additivity="false" 不在繼承 rootlogger 對象
 -->
 <AsyncLogger name="com.hk" level="info" includeLocation="false" additivity="false">
 <AppenderRef ref="File" />
 </AsyncLogger>

 <Root level="trace">
 <!--指定日志使用的處理器-->
 <AppenderRef ref="Console" includeLocation="true"/>
 </Root>
 </Loggers>
</Configuration>           

如上配置: com.hk日志是異步的,root日志是同步的。

使用異步日志需要注意的問題:

1. 如果使用異步日志,AsyncAppender、AsyncLogger和全局日志,不要同時出現。性能會和AsyncAppender一緻,降至最低。

2. 設定includeLocation=false ,列印位置資訊會急劇降低異步日志的性能,比同步日志還要慢。