1. 程式人生 > >log4j升級為log4j2(不需要改動程式碼)

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:

  1. They must not access methods and classes internal to the Log4j 1.x implementation such as Appenders, LoggerRepository or Category's callAppendersmethod.
  2. They must not programmatically configure Log4j.
  3. 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>