log4j升級為log4j2(不需要改動程式碼)
公司的專案決定升級log4j,因為log4j2有一個自動刪除日誌的功能,這樣可以減輕運維的一些工作,而且在多執行緒環境下,log4j2的非同步日誌系統比log4j和logback提高了十倍的效能(吞吐量和延遲率),官方原文如下:
Log4j 2 contains next-generation Asynchronous Loggers based on the LMAX Disruptor library. In multi-threaded scenarios Asynchronous Loggers have 10 times higher throughput and orders of magnitude lower latency than Log4j 1.x and Logback.
因為是升級,原專案用的是log4j或者self4j列印日誌,獲取logger的方式不同
比如log4j:
import org.apache.log4j.Logger;
private static final Logger LOGGER = Logger.getLogger(xxxx.class);
比如self4j:
import org.slf4j.Logger; import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(xxxx.class);
而如果用log4j2的話,API將有所不同:
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;
private static final Logger logger = LogManager.getLogger(xxxx.class);
如果在升級的過程中,我們要去改程式碼的話,那將是一項很大的繁瑣工程,log4j2架構已經考慮到這一點,給我們提供了轉換的包,我們只需要匯入幾個轉換包就可以使用log4j2,而且還不需要修改程式碼。
官方原文:
Perhaps the simplest way to convert to using Log4j 2 is to replace the log4j 1.x jar file with Log4j 2's log4j-1.2-api.jar. However, to use this successfully applications must meet the following requirements:
- They must not access methods and classes internal to the Log4j 1.x implementation such as Appenders, LoggerRepository or Category's callAppendersmethod.
- They must not programmatically configure Log4j.
- They must not configure by calling the classes DOMConfigurator or PropertyConfigurator
第一步:我這裡是maven專案,就以maven專案為例子,進行講解了
刪掉pom.xml檔案中關於log4j的依賴,新增新依賴
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
<!-- <scope>provided</scope> -->
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
<!-- <scope>provided</scope> -->
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.7</version>
<scope>runtime</scope>
</dependency>
log4j-1.2-api為log4j和log4j2的連線包。 第二步:刪掉以前的log4j.properties,改為log4j2.xml,這裡起名字的時候,不要寫錯了
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="info">
<Properties>
<Property name="LOG_HOME">${sys:catalina.base}/var/logs</Property>
<Property name="APP_LOG_HOME">${LOG_HOME}/uas</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<!-- 控制檯只輸出level及以上級別的資訊(onMatch),其他的直接拒絕(onMismatch) -->
<!-- <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"
/> -->
<!-- 輸出日誌的格式 -->
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
</Console>
<RollingRandomAccessFile name="uas_appender"
immediateFlush="true" fileName="${APP_LOG_HOME}/uas.log"
filePattern="${APP_LOG_HOME}/uas.log.%d{yyyy-MM-dd}.gz">
<!-- %d{yyyy-MM-dd HH:mm:ss, SSS} : 日誌生產時間 %p : 日誌輸出格式 %c : logger的名稱
%m : 日誌內容,即 logger.info("message") %n : 換行符 %C : Java類名 %L : 日誌輸出所在行數 %M
: 日誌輸出所在方法名 hostName : 本地機器名 hostAddress : 本地ip地址 -->
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M --
%msg%xEx%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"
modulate="true" />
</Policies>
<!-- 最多備份30天以內的日誌,此處為策略限制,Delete中可以按自己需要用正則表示式編寫 -->
<!-- DefaultRolloverStrategy欄位中加入max=“30”經測試是配合SizeBasedTriggeringPolicy限制%i的存在數量,並沒有發現是網上流傳的是最多儲存多少個檔案的限制,也或許是我寫的有問題 -->
<DefaultRolloverStrategy>
<Delete basePath="${APP_LOG_HOME}" maxDepth="1">
<IfFileName glob="uas.log.*.gz" />
<IfLastModified age="30d" />
</Delete>
</DefaultRolloverStrategy>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<logger name="org.spring" level="error" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="uas_appender" />
</logger>
<logger name="org.springframework" level="error" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="uas_appender" />
</logger>
<logger name="org.apache.zookeeper" level="error" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="uas_appender" />
</logger>
<logger name="com.alibaba.dubbo" level="error" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="uas_appender" />
</logger>
<logger name="xx.xx.xx" level="info" additivity="false">
<AppenderRef ref="Console" />
<appender-ref ref="uas_appender" />
</logger>
<root level="info">
<appender-ref ref="Console" />
<appender-ref ref="uas_appender" />
</root>
</Loggers>
</configuration>
這裡需要注意的有以下幾點:
1.log4j2.*版本中獲取home路徑是${sys:catalina.base} 2.要在<root>標籤中新增<appender-ref ref="Console"/>,<appender-ref ref="log"/>才能在控制檯、和檔案中列印日誌
第三步:在web.xml中配置
註釋掉以前關於載入log4j的配置,重新配置,這裡我的log4j2.xml放在classpath/conf下
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>classpath:conf/log4j2.xml</param-value>
</context-param>
配置放在web.xml的<display-name/>下方
如此log4j升級log4j2升級成功。
擴充套件:如果原專案中用的是self4j列印日誌,那麼導包的時候需要匯入:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>