log4j及log4j2在Spring MVC中的使用.md
目錄
- 一、log4j配置
- 二、log4j2配置
項目已上線許久,項目中使用的是log4j 1.x版本,本來日誌也可以正常記錄,但是運維報怨說,你們的日誌太大了,catalina.out日誌輸出無限大,以致有些應用出現服務器存儲告警,所以建議我們:
“應用日誌必須對接公司統一日誌平臺,若同時也存放在本地服務器,則統一放在容器根目錄下的單獨文件夾,文件夾名稱帶有log字樣,日誌文件按日期或大小歸檔,單個日誌文件超過20M的文件需要在歸檔時同時壓縮,默認只保留最近一個月的日誌,由代碼實現自動清理。”
總結日誌管理需求:
- 日誌寫入到統一日誌平臺(ELK日誌平臺);
- 本地日誌文件需按日期或大小歸檔;
- 單個日誌文件如超過20M需在歸檔時壓縮;
- 自動清理日誌,默認保留近一個月日誌;
- 關閉catalina.out日誌輸出;
鑒於以上需求,我發現log4j 1.x版本有些做不到,而log4j 2.x版本正好可以很好的滿足:
- Tomcat標準部署通過log4j配置無法關閉catalina.out日誌輸出;
- 無法自動清理日誌,僅保存近一個月日誌;
- 無法對超過20M的日誌文件在歸檔時自動壓縮;
備註:不升級log4j,如何解決以上問題?
1.通過Tomcat配置關閉catalina.out日誌輸出。
# 直接找到Tomcat下bin/catalina.sh文件中以下代碼片段: if [ -z "$CATALINA_OUT" ] ; then CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out # 將上面的內容修改成下面內容即可: if [ -z "$CATALINA_OUT" ] ; then CATALINA_OUT=/dev/null # 輸入到/dev/null黑洞
2.通過編寫服務器腳本、定時任務實現日誌清理和壓縮;
以上兩種方法也可以達到同樣的目的,但是運維的同學才不願意這麽幹,給你們提供個web容器,其它最好你們程序自己實現:)
log4j2是log4j的升級版,log4j2除了可以滿足以上需求,聽說性能也更好,將舊項目中的log4j升級到log4j2的成本也較低。
一、log4j配置
官方文檔:http://logging.apache.org/log4j/1.2/apidocs
1. Maven包引入
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.19</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.19</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
2. log4j.properties配置文件
log4j約定了其配置文件在默認加載類的路徑下,即classpath的根路徑,所以如最終發布在classpath根路徑下,則在使用時無需指定路徑。
### set log levels ###
log4j.rootLogger=debug,stdout,debug,error,rsyslog
#log4j.rootLogger=debug,debug,error,rsyslog
### 配置根Logger:設定日誌記錄的最低級別 ###
log4j.category.org.springframework=ERROR
log4j.category.org.apache=INFO
log4j.logger.org.hibernate=ERROR
### 輸出到控制臺 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}][%t] %l %m %n
### 輸出到日誌文件 ###
log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender
log4j.appender.debug.File = ${catalina.home}/msp-logs/info.log
log4j.appender.debug.datePattern=‘.‘yyyy-MM-dd
log4j.appender.debug.append=true
log4j.appender.debug.Threshold=DEBUG
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}][%t] %l %m %n
### ERROR輸出到日誌文件 ###
log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error.File = ${catalina.home}/msp-logs/error.log
log4j.appender.error.datePattern=‘.‘yyyy-MM-dd
log4j.appender.error.append=true
log4j.appender.error.Threshold=ERROR
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}] %l %m %n
#appender rsyslog 端口不可配置,使用默認的:514
log4j.appender.rsyslog=org.apache.log4j.net.SyslogAppender
log4j.appender.rsyslog.syslogHost=11.4.74.26
log4j.appender.rsyslog.Facility=local1
log4j.appender.rsyslog.FacilityPrinting=true
log4j.appender.rsyslog.header=true
log4j.appender.rsyslog.layout=org.apache.log4j.PatternLayout
log4j.appender.rsyslog.layout.conversionPattern=WEIXIN-MSP %d [%-5p] [%t] - %m%n
3. web.xml配置
web.xml配置文件中添加log4j監聽器,其中webAppRootKey配置,可將對應日誌寫入到對應的項目下,缺省值是“webapp.root”,最好要定義,值隨便填寫,否則對於tomcat部署多個項目時,會沖突。
<!-- log4j配置 -->
<!-- 配置文件如放默認路徑,log4jConfigLocation可不配 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF/log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>600000</param-value>
</context-param>
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webName.root</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
</listener>
二、log4j2配置
1. Maven包引入
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.3</version>
</dependency>
2. log4j2.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!--status指定log4j本身(log4j2這個程序)打印日誌的級別-->
<Configuration status="WARN" packages="">
<Appenders>
<!--輸出至控制臺的配置-->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd HH:mm:ss} %class{36} [%p] %m%n"/>
</Console>
<!--輸出至日誌文件的配置-->
<RollingFile name="errorFile" fileName="${sys:catalina.base}/logs/error.log"
filePattern="${sys:catalina.base}/logs/error.log.%d{yyyyMMdd}">
<PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd HH:mm:ss} %class{36} [%p] %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy modulate="true"/>
</Policies>
</RollingFile>
<RollingFile name="infoFile" fileName="${sys:catalina.base}/wx-logs/info.log"
filePattern="${sys:catalina.base}/wx-logs/info.log.%d{yyyyMMdd}">
<PatternLayout charset="utf-8" pattern="%d{yyyy-MM-dd HH:mm:ss} %class{36} [%p] %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy modulate="true"/>
</Policies>
</RollingFile>
<!--輸出至日誌平臺的配置 log4j2寫入日誌平臺無法識別appName,希望采用facility=auth能與其它系統區別開-->
<Syslog name="SYSLOG" format="RFC5424" host="11.4.74.26" port="514"
protocol="UDP" appName="WEIXIN-VUE-API" includeMDC="true"
facility="USER" enterpriseNumber="18060" newLine="true"
messageId="Audit" mdcId="mdc" id="App"
connectTimeoutMillis="1000" reconnectionDelayMillis="5000">
<LoggerFields>
<KeyValuePair key="thread" value="%t"/>
<KeyValuePair key="priority" value="%p"/>
<KeyValuePair key="category" value="%c"/>
<KeyValuePair key="exception" value="%ex"/>
<KeyValuePair key="message" value="%m"/>
</LoggerFields>
</Syslog>
</Appenders>
<!--日誌級別:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.-->
<Loggers>
<!--只有定義了logger並引入的appender,appender才會生效-->
<Logger name="error" level="error" additivity="false">
<!--Logger的子節點,用來指定該日誌輸出到哪個Appender,如果沒有指定,就會默認繼承自Root.
如果指定了,那麽會在指定的這個Appender和Root的Appender中都會輸出,此時我們可以設置Logger的additivity="false"
只在自定義的Appender中進行輸出-->
<AppenderRef ref="SYSLOG"/>
<AppenderRef ref="errorFile"/>
</Logger>
<!--Root用來指定項目的根日誌,沒有單獨指定Logger,會統一輸出到Root中-->
<Root level="Info" additivity="false">
<AppenderRef ref="SYSLOG"/>
<AppenderRef ref="infoFile"/>
</Root>
</Loggers>
</Configuration>
3. 使用方式
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
// 普通使用
private static final Logger LOGGER = LogManager.getLogger(HelloController.class);
LOGGER.error("error log."); // 會命中log4j2配置的Root項
// 高級使用
LogManager.getLogger("LoggerName01").error(error log.); 會命中log4j2配置的LoggerName01項
LogManager.getLogger("LoggerName02").error(error log.); 會命中log4j2配置的LoggerName02項
4. 按天分日誌文件
<RollingFile name="error_appender" fileName="${sys:catalina.base}/wx-logs/error.log" filePattern="${sys:catalina.base}/wx-logs/error-%d{yyyy-MM-dd}.log">
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%thread] %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
</Policies>
</RollingFile>
5. 按大小分日誌文件
<RollingFile name="error_appender" fileName="${sys:catalina.base}/wx-logs/error.log" filePattern="${sys:catalina.base}/wx-logs/error-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="%-d{yyyy-MM-dd HH:mm:ss} [%thread] %m%n"/>
<SizeBasedTriggeringPolicy size="100 MB" />
</RollingFile>
log4j及log4j2在Spring MVC中的使用.md