Java猿社區(qū)之日志組件升級Log4j2

@[toc]

前言

升級前提介紹:在線客服關(guān)于升級Log4j2記錄日志的總結(jié)

本次升級樣例項目:

  • ddky-backManage-all
  • ddky-report-web

參考:
http://logging.apache.org/log4j/2.x/manual/webapp.html#Servlet-2.5

升級web

修改pom

刪除舊依賴

  • 此處需要刪除各包下引用的低版本log4j,使用excludes去除
  • 可以使用mvn dependency:tree查看沖突和低版本log4j引用情況
  • idea可以直接使用Digrams -> show dependencies
                <!-- Log4j 刪除舊版本 -->
        <!--<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>-->
        <!--<dependency>-->
            <!--<groupId>log4j</groupId>-->
            <!--<artifactId>log4j</artifactId>-->
            <!--<version>${log4j.version}</version>-->
        <!--</dependency>-->
        
        <!-- 排除log4j和logback依賴包 -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
            <exclusions>
                <!--  排除log4j1的方式  -->
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
                <!--  排除logback的方式  -->
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        
        <!-- 去除disconfig log4j1 -->
        <dependency>
            <groupId>com.baidu.disconf</groupId>
            <artifactId>disconf-client</artifactId>
            <version>2.6.35-ddky</version>
            <exclusions>
                <exclusion>
                     <groupId>commons-io</groupId>
                     <artifactId>commons-io</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
            <exclusions>
                <!--  排除log4j1的方式  -->
                <exclusion>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                </exclusion>
                <!--  排除logback的方式  -->
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        
        ...等等等

引入log4j2依賴:
版本統(tǒng)一使用:

  • log4j-2.11.2
  • disruptor-3.4.2

<!-- ***********Log4j2升級開始********** -->

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

        <!-- slf4j門面包 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>

        <!-- log4j2核心包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.11.2</version>
        </dependency>

        <!-- log4j2門面包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.11.2</version>
        </dependency>

        <!-- 該包是 log4j 升級到 log4j2的必須包 使用該包 不需要修改以前的 Logger.getLogger()這種獲取對象的方式 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-1.2-api</artifactId>
            <version>2.11.2</version>
        </dependency>
        <!-- 該包是slf4j 升級到 log4j2的必須包 使用該包 其他依賴jar中依賴slf4j 不會報錯 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.11.2</version>
        </dependency>

        <!-- web項目需要引用此包 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
            <version>2.11.2</version>
        </dependency>

        <!-- 橋接:告訴commons logging使用Log4j2 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jcl</artifactId>
            <version>2.11.2</version>
            <scope>runtime</scope>
        </dependency>

        <!-- ***********Log4j2升級結(jié)束********** -->

配置web.xml

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-mMkdrvJ3-1578400083971)(./1578389815402.png)]
升級web-app到2.5版本(推薦,由于公司項目servlet都采用2.5版本)

原先:

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

改為:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

修改原先的配置

        <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener
        </listener-class>
    </listener>
        <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>classpath:log4j.properties</param-value>
    </context-param>

添加新配置:

    <!--日志升級開始-->
    <listener>
        <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
    </listener>
    <filter>
        <filter-name>log4jServletFilter</filter-name>
        <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>log4jServletFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
        <!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
        <!-- <dispatcher>ASYNC</dispatcher> -->
    </filter-mapping>

    <context-param>
        <param-name>log4jConfiguration</param-name>
        <param-value>/WEB-INF/classes/log4j2.xml</param-value>
        <!--<param-value>classpath:log4j2.xml</param-value>-->
    </context-param>
    <!--<context-param>-->
        <!--<param-name>log4jRefreshInterval</param-name>-->
        <!--<param-value>1000</param-value>-->
    <!--</context-param>-->
    <!--日志升級結(jié)束-->
升級web-app到3.0版本(不推薦,升級改動范圍大)

原先:

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

改為:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

添加新配置:

    <!--日志升級開始-->
    <context-param>
        <param-name>log4jConfiguration</param-name>
        <param-value>/WEB-INF/classes/log4j2.xml</param-value>
        <!--<param-value>classpath:log4j2.xml</param-value>-->
    </context-param>
    <context-param>
        <param-name>isLog4jAutoInitializationDisabled</param-name>
        <param-value>true</param-value>
    </context-param>
    <!--日志升級結(jié)束-->

升級pom依賴servlet-api版本到3.0

創(chuàng)建resources/log4j2.xml

并備份和刪除原先的log4j.properties

創(chuàng)建log4j2.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="30" strict="true">

    <Properties>
        <!-- 日志輸出級別 -->
        <Property name="LOG_DEBUG_LEVEL" value="debug"/>
        <Property name="LOG_INFO_LEVEL" value="info"/>
        <Property name="LOG_WARN_LEVEL" value="warn"/>
        <!-- error級別日志 -->
        <Property name="LOG_ERROR_LEVEL" value="error"/>
        <!-- 在當(dāng)前目錄下創(chuàng)建名為log目錄做日志存放的目錄 -->
        <!--<Property name="LOG_HOME" value="./log"/>-->
        <Property name="LOG_HOME" value="E:\dd\codes\o2o\20160219\web\ddky_report_web\log"/>
        <!-- 檔案日志存放目錄 -->
        <Property name="LOG_ARCHIVE" value="${LOG_HOME}/archive"/>
        <!-- 模塊名稱, 影響日志配置名,日志文件名,根據(jù)自己項目進(jìn)行配置 -->
        <Property name="LOG_MODULE_NAME" value="ddky-report-web"/>
        <!-- 日志文件大小,超過這個大小將被壓縮 -->
        <Property name="LOG_MAX_SIZE" value="100 MB"/>
        <!-- 保留多少天以內(nèi)的日志 -->
        <Property name="LOG_DAYS" value="30"/>
        <!--輸出日志的格式:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度, %msg:日志消息,%n是換行符 -->
        <Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/>
        <!--interval屬性用來指定多久滾動一次-->
        <Property name="TIME_BASED_INTERVAL" value="1"/>
    </Properties>

    <Appenders>
        <!-- 控制臺輸出 -->
        <Console name="STDOUT" target="SYSTEM_OUT">
            <!--輸出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <!--控制臺只輸出level及其以上級別的信息(onMatch),其他的直接拒絕(onMismatch)-->
            <ThresholdFilter level="${LOG_DEBUG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
        </Console>

        <!--只記錄debug級別以上的日志,與info級別的日志分不同的文件保存-->
        <RollingRandomAccessFile name="RollingRandomAccessFileDebug"
                                 fileName="${LOG_HOME}/debug.log"
                                 filePattern="${LOG_ARCHIVE}/debug-%d{yyyy-MM-dd}-%i.log.gz"
                                 immediateFlush="true">
            <Filters>
                <ThresholdFilter level="${LOG_DEBUG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy max="${LOG_DAYS}"/>
        </RollingRandomAccessFile>

        <!-- 這個會打印出所有的info級別以上,error級別一下的日志,每次大小超過size或者滿足TimeBasedTriggeringPolicy,則日志會自動存入按年月日建立的文件夾下面并進(jìn)行壓縮,作為存檔-->
        <!--異步日志會自動批量刷新,所以將immediateFlush屬性設(shè)置為false-->
        <RollingRandomAccessFile name="RollingRandomAccessFileInfo"
                                 fileName="${LOG_HOME}/info.log"
                                 filePattern="${LOG_ARCHIVE}/info-%d{yyyy-MM-dd}-%i.log.gz"
                                 immediateFlush="false">
            <Filters>
                <!--如果是error級別拒絕,設(shè)置 onMismatch="NEUTRAL" 可以讓日志經(jīng)過后續(xù)的過濾器-->
                <ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/>
                <!--如果是info\warn輸出-->
                <ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval屬性用來指定多久滾動一次,根據(jù)當(dāng)前filePattern設(shè)置是1天滾動一次-->
                <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
            </Policies>
            <!-- DefaultRolloverStrategy屬性如不設(shè)置,則默認(rèn)同一文件夾下最多保存7個文件-->
            <DefaultRolloverStrategy max="${LOG_DAYS}"/>
        </RollingRandomAccessFile>

        <!--只記錄error級別以上的日志,與info級別的日志分不同的文件保存-->
        <RollingRandomAccessFile name="RollingRandomAccessFileError"
                                 fileName="${LOG_HOME}/error.log"
                                 filePattern="${LOG_ARCHIVE}/error-%d{yyyy-MM-dd}-%i.log.gz"
                                 immediateFlush="false">
            <Filters>
                <ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy max="${LOG_DAYS}"/>
        </RollingRandomAccessFile>

        <!--只記錄warn級別以上的日志,與info級別的日志分不同的文件保存-->
        <RollingRandomAccessFile name="RollingRandomAccessFileWarn"
                                 fileName="${LOG_HOME}/warn.log"
                                 filePattern="${LOG_ARCHIVE}/warn-%d{yyyy-MM-dd}-%i.log.gz"
                                 immediateFlush="false">
            <Filters>
                <ThresholdFilter level="${LOG_WARN_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy max="${LOG_DAYS}"/>
        </RollingRandomAccessFile>

    </Appenders>

    <Loggers>

        <!-- 本機環(huán)境使用 -->
        <!--<Root level="${LOG_DEBUG_LEVEL}">-->
            <!--<AppenderRef ref="STDOUT"/>-->
            <!--<AppenderRef ref="RollingRandomAccessFileInfo"/>-->
            <!--<AppenderRef ref="RollingRandomAccessFileError"/>-->
            <!--<AppenderRef ref="RollingRandomAccessFileDebug"/>-->
            <!--<AppenderRef ref="RollingRandomAccessFileWarn"/>-->
        <!--</Root>-->

        <!-- 開發(fā)環(huán)境使用 -->
        <Root level="${LOG_INFO_LEVEL}">
            <AppenderRef ref="STDOUT"/>
            <AppenderRef ref="RollingRandomAccessFileInfo"/>
            <AppenderRef ref="RollingRandomAccessFileError"/>
            <AppenderRef ref="RollingRandomAccessFileWarn"/>
        </Root>

        <!-- 生產(chǎn)預(yù)發(fā)布環(huán)境使用 -->
        <!--<Root level="${LOG_INFO_LEVEL}" includeLocation="false">-->
        <!--<AppenderRef ref="RollingRandomAccessFileInfo"/>-->
        <!--<AppenderRef ref="RollingRandomAccessFileError"/>-->
        <!--</Root>-->


        <!-- 第三方日志系統(tǒng) -->
        <logger name="org.springframework.core" level="info" />
        <logger name="org.springframework.beans" level="info" />
        <logger name="org.springframework.context" level="info" />
        <logger name="org.springframework.web" level="info" />
        <logger name="org.jboss.netty" level="warn" />
        <logger name="org.apache.http" level="warn" />

    </Loggers>

</Configuration>

修改log4j2.xml中屬性

  • immediateFlush:如果使用異步日志,請設(shè)置為false,同步日志,請設(shè)置為true
  • LOG_MODULE_NAME:模塊名稱,建議按照項目模塊命名
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-zItlk7Om-1578400083972)(./1578389836501.png)]
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-JAsazHkm-1578400083973)(./1578389844163.png)]

配置log4j2.component.properties

# 設(shè)置異步日志系統(tǒng)屬性
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
AsyncLoggerConfig.WaitStrategy=Sleep
#AsyncLoggerConfig.RingBufferSize=10240

Service服務(wù)

打印druid sql—修改applicationContext.xml

添加如下配置:

    <!-- druid 打印sql日志 -->
    <bean id="log-filter" class="com.alibaba.druid.filter.logging.Slf4jLogFilter">
        <property name="connectionLogEnabled" value="false"/>
        <property name="statementLogEnabled" value="false"/>
        <property name="resultSetLogEnabled" value="true"/>
        <property name="statementExecutableSqlLogEnable" value="true"/>
    </bean>

引入log-filter

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-u376jDrk-1578400083973)(./1578389861224.png)]

log4j2.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="30" strict="true">

    <Properties>
        <!-- 日志輸出級別 -->
        <Property name="LOG_DEBUG_LEVEL" value="debug"/>
        <Property name="LOG_INFO_LEVEL" value="info"/>
        <Property name="LOG_WARN_LEVEL" value="warn"/>
        <!-- error級別日志 -->
        <Property name="LOG_ERROR_LEVEL" value="error"/>
        <!-- 在當(dāng)前目錄下創(chuàng)建名為log目錄做日志存放的目錄 -->
        <Property name="LOG_HOME" value="./log"/>
        <!--<Property name="LOG_HOME" value="E:\dd\codes\log"/>-->
        <!--<Property name="LOG_HOME" value="E:\dd\codes\o2o\20160219\web\ddky_report_web\log"/>-->
        <!-- 檔案日志存放目錄 -->
        <Property name="LOG_ARCHIVE" value="${LOG_HOME}/archive"/>
        <!-- 模塊名稱, 影響日志配置名,日志文件名,根據(jù)自己項目進(jìn)行配置 -->
        <Property name="LOG_MODULE_NAME" value="ddky-backManage-all"/>
        <!-- 日志文件大小,超過這個大小將被壓縮 -->
        <Property name="LOG_MAX_SIZE" value="100 MB"/>
        <!-- 保留多少天以內(nèi)的日志 -->
        <Property name="LOG_DAYS" value="30"/>
        <!--輸出日志的格式:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度, %msg:日志消息,%n是換行符 -->
        <Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/>
        <!--interval屬性用來指定多久滾動一次-->
        <Property name="TIME_BASED_INTERVAL" value="1"/>
    </Properties>

    <Appenders>
        <!-- 控制臺輸出 -->
        <Console name="STDOUT" target="SYSTEM_OUT">
            <!--輸出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <!--控制臺只輸出level及其以上級別的信息(onMatch),其他的直接拒絕(onMismatch)-->
            <ThresholdFilter level="${LOG_DEBUG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
        </Console>

        <!--只記錄debug級別以上的日志,與info級別的日志分不同的文件保存-->
        <RollingRandomAccessFile name="RollingRandomAccessFileDebug"
                                 fileName="${LOG_HOME}/debug.log"
                                 filePattern="${LOG_ARCHIVE}/debug-%d{yyyy-MM-dd}-%i.log.gz"
                                 immediateFlush="true">
            <Filters>
                <ThresholdFilter level="${LOG_DEBUG_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy max="${LOG_DAYS}"/>
        </RollingRandomAccessFile>

        <!-- 這個會打印出所有的info級別以上,error級別一下的日志,每次大小超過size或者滿足TimeBasedTriggeringPolicy,則日志會自動存入按年月日建立的文件夾下面并進(jìn)行壓縮,作為存檔-->
        <!--異步日志會自動批量刷新,所以將immediateFlush屬性設(shè)置為false-->
        <RollingRandomAccessFile name="RollingRandomAccessFileInfo"
                                 fileName="${LOG_HOME}/info.log"
                                 filePattern="${LOG_ARCHIVE}/info-%d{yyyy-MM-dd}-%i.log.gz"
                                 immediateFlush="true">
            <Filters>
                <!--如果是error級別拒絕,設(shè)置 onMismatch="NEUTRAL" 可以讓日志經(jīng)過后續(xù)的過濾器-->
                <ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/>
                <!--如果是info\warn輸出-->
                <ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!--interval屬性用來指定多久滾動一次,根據(jù)當(dāng)前filePattern設(shè)置是1天滾動一次-->
                <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
            </Policies>
            <!-- DefaultRolloverStrategy屬性如不設(shè)置,則默認(rèn)同一文件夾下最多保存7個文件-->
            <DefaultRolloverStrategy max="${LOG_DAYS}"/>
        </RollingRandomAccessFile>

        <!--只記錄error級別以上的日志,與info級別的日志分不同的文件保存-->
        <RollingRandomAccessFile name="RollingRandomAccessFileError"
                                 fileName="${LOG_HOME}/error.log"
                                 filePattern="${LOG_ARCHIVE}/error-%d{yyyy-MM-dd}-%i.log.gz"
                                 immediateFlush="true">
            <Filters>
                <ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy max="${LOG_DAYS}"/>
        </RollingRandomAccessFile>

        <!--只記錄warn級別以上的日志,與info級別的日志分不同的文件保存-->
        <RollingRandomAccessFile name="RollingRandomAccessFileWarn"
                                 fileName="${LOG_HOME}/warn.log"
                                 filePattern="${LOG_ARCHIVE}/warn-%d{yyyy-MM-dd}-%i.log.gz"
                                 immediateFlush="true">
            <Filters>
                <ThresholdFilter level="${LOG_WARN_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy max="${LOG_DAYS}"/>
        </RollingRandomAccessFile>

        <!--druid的日志記錄追加器-->
        <RollingRandomAccessFile name="druidSqlRollingFile" fileName="${LOG_HOME}/druid-sql.log"
                                 filePattern="${LOG_ARCHIVE}/druid-sql-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
            </Policies>
            <DefaultRolloverStrategy max="${LOG_DAYS}"/>
        </RollingRandomAccessFile>

    </Appenders>

    <Loggers>

        <!-- 本機環(huán)境使用 -->
        <!--<Root level="${LOG_DEBUG_LEVEL}" includeLocation="true" additivity="true">-->
        <!--<AppenderRef ref="STDOUT"/>-->
        <!--<AppenderRef ref="RollingRandomAccessFileInfo"/>-->
        <!--<AppenderRef ref="RollingRandomAccessFileError"/>-->
        <!--<AppenderRef ref="RollingRandomAccessFileDebug"/>-->
        <!--<AppenderRef ref="RollingRandomAccessFileWarn"/>-->
        <!--</Root>-->

        <!-- 開發(fā)環(huán)境使用 -->
        <Root level="${LOG_INFO_LEVEL}" includeLocation="true" additivity="true">
            <AppenderRef ref="STDOUT"/>
            <AppenderRef ref="RollingRandomAccessFileInfo"/>
            <AppenderRef ref="RollingRandomAccessFileError"/>
            <AppenderRef ref="RollingRandomAccessFileWarn"/>
        </Root>

        <!--記錄druid-sql的記錄-->
        <logger name="druid.sql.Statement" level="debug" additivity="false">
        <appender-ref ref="druidSqlRollingFile"/>
        </logger>

        <!-- 生產(chǎn)預(yù)發(fā)布環(huán)境使用 -->
        <!--<Root level="${LOG_INFO_LEVEL}" includeLocation="false" additivity="false">-->
        <!--<AppenderRef ref="RollingRandomAccessFileInfo"/>-->
        <!--<AppenderRef ref="RollingRandomAccessFileError"/>-->
        <!--</Root>-->


        <!-- 第三方日志系統(tǒng) -->
        <logger name="org.springframework.core" level="info" />
        <logger name="org.springframework.beans" level="info" />
        <logger name="org.springframework.context" level="info" />
        <logger name="org.springframework.web" level="info" />
        <logger name="org.jboss.netty" level="warn" />
        <logger name="org.apache.http" level="warn" />
        <Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
        <Logger name="org.apache.catalina.util.LifecycleBase" level="error" />
        <Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
        <logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
        <Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
        <Logger name="org.crsh.plugin" level="warn" />
        <logger name="org.crsh.ssh" level="warn"/>
        <Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
        <Logger name="org.hibernate.validator.internal.util.Version" level="warn" />
        <logger name="org.springframework.boot.actuate.autoconfigure.CrshAutoConfiguration" level="warn"/>
        <logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
        <logger name="org.thymeleaf" level="warn"/>

    </Loggers>

</Configuration>

配置log4j2.component.properties

# 設(shè)置異步日志系統(tǒng)屬性
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
AsyncLoggerConfig.WaitStrategy=Sleep
#AsyncLoggerConfig.RingBufferSize=10240

開關(guān)異步日志

通過修改log4j2.component.properties屬性
當(dāng)需要開啟異步日志時:

# 設(shè)置異步日志系統(tǒng)屬性
log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
AsyncLoggerConfig.WaitStrategy=Sleep

當(dāng)需要關(guān)閉異步日志,開啟同步日志時:(直接注釋配置即可)

# 設(shè)置異步日志系統(tǒng)屬性
#log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
#AsyncLoggerConfig.WaitStrategy=Sleep

如何使用

@Slf4j 或 @Log4j2注解 和 手動創(chuàng)建Logger

  • 通過引入lombok包, 直接在類上引用@Slf4j 或 @Log4j2注解
  • 通過手動創(chuàng)建Logger類(slf4j或者log4j2)
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>

測試示例:

package com.ddky;

import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
//import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.async.AsyncLoggerContextSelector;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.CountDownLatch;

/**
 * @program: 20160219
 * @description:
 * @author: zhouzhixiang
 * @date: 2020-01-06
 * @company: 叮當(dāng)快藥科技集團(tuán)有限公司
 **/
//@Slf4j
@Log4j2
public class Log4j2Test {

    // 使用slf4j
    private static final Logger log = LoggerFactory.getLogger(Log4j2Test.class);
    private int totalThread = 50;
    // 使用log4j2
//    private static final Logger log = LogManager.getLogger(Log4j2Test.class);

    @Test
    public void testLog() {
        log.info("Test*******************************************");
        log.error("Test*******************************************");
        log.warn("Test*******************************************");
        log.debug("Test*******************************************");
    }

//    @Test
    public void fixedPringting() throws InterruptedException {
        log.info("log4j2 100萬 start printing");
        final CountDownLatch cdl = new CountDownLatch(totalThread);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < totalThread; i++) {
            new Thread(() -> {
                for (int j = 0; j < 200000; j++) {
                    log.info("log4j2 performance test " +j);
                }
            }).start();
                    cdl.countDown();
        }
        cdl.await();
        long endTime = System.currentTimeMillis();
        log.info("log4j2 100萬 end cost time "+ (endTime - startTime));
    }

    public static void main(String[] args) throws InterruptedException {
        log.info("log4j2 1000萬 start printing");
        Integer totalThread = 50;
        final CountDownLatch cdl = new CountDownLatch(totalThread);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < totalThread; i++) {
            new Thread(() -> {
                for (int j = 0; j < 2000; j++) {
                    log.info("log4j2 performance test "+ j);
                }
                cdl.countDown();
            }).start();
        }
        cdl.await();
        long endTime = System.currentTimeMillis();
        log.error("log4j2 1000萬 end cost time = "+ (endTime - startTime));
    }

    @Test
    public void isAsyncLog() {
        log.info("是否為異步日志1:"+ AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志2:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志3:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志4:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志5:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志6:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志7:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志8:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志9:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志10:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志11:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志11:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志11:"+AsyncLoggerContextSelector.isSelected());
        log.info("是否為異步日志11:"+AsyncLoggerContextSelector.isSelected());
    }

    @Test
    public void testFori() {
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                isAsyncLog();
            }).start();
            log.info(String.valueOf(i));
//            log.error(String.valueOf(i));
//            log.debug(String.valueOf(i));
//            log.warn(String.valueOf(i));
        }
    }
}

注意事項

  • 對于需要審計操作的日志,請開啟同步日志,不建議開啟異步日志。
  • 引入jar依賴注意版本統(tǒng)一管理(以上引入未作版本管理,僅作參考)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容