1. 程式人生 > >log4j及log4j2在Spring MVC中的使用.md

log4j及log4j2在Spring MVC中的使用.md

aci ESS facility vue log4j配置 status pro 寫入 4.2

目錄

  • 一、log4j配置
  • 二、log4j2配置

項目已上線許久,項目中使用的是log4j 1.x版本,本來日誌也可以正常記錄,但是運維報怨說,你們的日誌太大了,catalina.out日誌輸出無限大,以致有些應用出現服務器存儲告警,所以建議我們:

“應用日誌必須對接公司統一日誌平臺,若同時也存放在本地服務器,則統一放在容器根目錄下的單獨文件夾,文件夾名稱帶有log字樣,日誌文件按日期或大小歸檔,單個日誌文件超過20M的文件需要在歸檔時同時壓縮,默認只保留最近一個月的日誌,由代碼實現自動清理。”

總結日誌管理需求:

  1. 日誌寫入到統一日誌平臺(ELK日誌平臺);
  2. 本地日誌文件需按日期或大小歸檔;
  3. 單個日誌文件如超過20M需在歸檔時壓縮;
  4. 自動清理日誌,默認保留近一個月日誌;
  5. 關閉catalina.out日誌輸出;

鑒於以上需求,我發現log4j 1.x版本有些做不到,而log4j 2.x版本正好可以很好的滿足:

  1. Tomcat標準部署通過log4j配置無法關閉catalina.out日誌輸出;
  2. 無法自動清理日誌,僅保存近一個月日誌;
  3. 無法對超過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