Log4j 2 + Slf4j + Druid 的配置和使用

时间:2022-12-18 22:07:42

        Log4j 2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活。下面是结合slf4j的配置和使用过程:

1、引用依赖包及相关注释:
<properties>
    <!-- 配置可变版本号 -->
    <log4j.version>2.8.2</log4j.version>
</properties>
<!-- 0.log配置:Log4j2 + Slf4j -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-web</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <!-- 桥接:告诉Slf4j使用Log4j2 -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j-impl</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <!-- 桥接:告诉commons logging使用Log4j2 -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-jcl</artifactId>
      <version>${log4j.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.25</version>
    </dependency>

注:log4j-api-2.x 和 log4j-core-2.x是必须的,其他包根据需要引入,如下图所示: 

Log4j 2 + Slf4j + Druid 的配置和使用


2、配置(log4j2.xml配置文件): 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<!-- Log4j 2.x 配置文件。每30秒自动检查和应用配置文件的更新; -->
<Configuration status="warn" monitorInterval="30" strict="true" schema="Log4J-V2.2.xsd">
    <Appenders>
           <!-- 输出到控制台 -->
           <Console name="Console" target="SYSTEM_OUT">
               <!-- 需要记录的级别 -->
               <!-- <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" /> -->
               <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%F:%L) - %m%n" />
          </Console>

          <!-- 输出到文件,按天或者超过80MB分割 -->
          <RollingFile name="RollingFile" fileName="../logs/xjj.log"    filePattern="../logs/$${date:yyyy-MM}/xjj-%d{yyyy-MM-dd}-%i.log.gz">
               <!-- 需要记录的级别 -->
               <!-- <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> -->
               <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%F:%L) - %m%n" />
               <Policies>
                    <OnStartupTriggeringPolicy />
                    <TimeBasedTriggeringPolicy />
                    <SizeBasedTriggeringPolicy size="80 MB" />
               </Policies>
          </RollingFile>
     </Appenders>
     <Loggers>
          <Root level="info"> <!-- 全局配置 -->
               <AppenderRef ref="Console" />
               <AppenderRef ref="RollingFile"/>
          </Root>
          <!-- 为sql语句配置特殊的Log级别,方便调试 -->
          <Logger name="com.ray.dao" level="${log.sql.level}" additivity="false">
               <AppenderRef ref="Console" />
          </Logger>
     </Loggers>
</Configuration>


3、代码中使用:

package com.ray.test;

import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * @author Ray
 * @date 2018/5/29 0029
 */
@RunWith(SpringJUnit4ClassRunner.class) //使用Spring Junit4进行测试
@ContextConfiguration({"classpath:spring/*.xml"}) //加载配置文件
public class BaseJunit4Test {
}
package com.ray.test;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Ray
 * @date 2018/5/29 0029
 */
public class Log4j2Test extends BaseJunit4Test {

    private Logger logger = LoggerFactory.getLogger(Log4j2Test.class);

    @Test
    public void logTest(){
        logger.error("error");
        logger.debug("debug");
        logger.info("info");
        logger.trace("trace");
        logger.warn("warn");
        logger.error("error {}", "param");
    }
}

----------------------------------分割线---------------------------------------------

Druid搭配log4j2输出SQL语句和结果

1. 创建基于druid的logger

<!-- 创建基于druid的logger -->
    <bean id="log-filter" class="com.alibaba.druid.filter.logging.Log4j2Filter">
        <!-- 表示是否连接所有Connection相关的日志 -->
        <property name="connectionLogEnabled" value="false"/>
        <!-- 表示是否连接所有Statement相关的日志 -->
        <property name="statementLogEnabled" value="false"/>
        <!-- 表示是否显示结果集 -->
        <property name="resultSetLogEnabled" value="true"/>
        <!-- 表示是否显示SQL语句 -->
        <property name="statementExecutableSqlLogEnable" value="true"/>
    </bean>

2. 在 DruidDataSource中配置

<!-- 2.配置druid数据源 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!-- 配置连接池属性 -->
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        <!-- 配置初始化大小 -->
        <property name="initialSize" value="${initialSize}"/>
        <!-- 最大连接数量 -->
        <property name="maxActive" value="${maxActive}"/>
        <!-- 最小空闲连接 -->
        <property name="minIdle" value="${minIdle}"/>
        <!-- 超时等待时间 -->
        <property name="maxWait" value="${maxWait}"/>
        <!-- 配置间隔多久进行一次检测,检测需要关闭空闲连接,单位毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}"/>
        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}"/>

        <!-- 验证连接有效与否的SQL,不同的数据配置不同 -->
        <property name="validationQuery" value="SELECT 1"/>
        <!-- 检测连接是否有效 -->
        <property name="testWhileIdle" value="true"/>
        <!-- 从池中取出连接前进行检验,防止取到的连接不可用 -->
        <property name="testOnBorrow" value="true"/>
        <!-- 归还到池中前进行检验 -->
        <property name="testOnReturn" value="false"/>

        <!-- 打开PSCache,预缓存设置 -->
        <property name="poolPreparedStatements" value="true"/>
        <property name="maxPoolPreparedStatementPerConnectionSize" value="20"/>

        <!-- 开启Druid的监控统计功能 -->
        <property name="filters" value="stat,log4j2"/>

        <!-- 在 DruidDataSource中配置 -->
        <property name="proxyFilters">
            <list>
                <ref bean="log-filter"/>
            </list>
        </property>
    </bean>

proxyFilters是代理filter的意思,将我们在第一步创建的log-filter写入进去。

3. log4j2.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<!-- Log4j 2.x 配置文件。每30秒自动检查和应用配置文件的更新; -->
<configuration status="warn" monitorInterval="30" strict="true" schema="Log4J-V2.2.xsd">
    <Properties>
        <Property name="logdir">${sys:catalina.base}/logs</Property>
    </Properties>
    <appenders>
        <!-- 输出到控制台 -->
        <console name="Console" target="SYSTEM_OUT">
            <!-- 需要记录的级别 -->
            <!-- <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" /> -->
            <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %level [%C{36}.%M] - %msg%n"/>
        </console>
        <!-- 输出到文件,按天或者超过80MB分割 -->
        <rollingFile name="RollingFile" fileName="conerstone.log"
                     filePattern="${logdir}/logs/$${date:yyyy-MM}/xjj-%d{yyyy-MM-dd}-%i.log.gz">
            <!-- 需要记录的级别 -->
            <!-- <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> -->
            <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %level [%C{36}.%M] - %msg%n"/>
            <policies>
                <onStartupTriggeringPolicy/>
                <timeBasedTriggeringPolicy/>
                <sizeBasedTriggeringPolicy size="1 MB"/>
            </policies>
        </rollingFile>
    </appenders>
    <loggers>
        <!-- 全局配置 -->
        <root level="info">
            <appenderRef ref="Console"/>
            <appenderRef ref="RollingFile"/>
        </root>
        <logger name="org.springframework.web" level="debug" additivity="false">
            <appenderRef ref="Console"/>
        </logger>
        <logger name="com.ray.service" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>

        <!-- druid配置 -->
        <logger name="druid.sql.Statement" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
        <logger name="druid.sql.ResultSet" level="debug" additivity="false">
            <appender-ref ref="Console"/>
        </logger>
    </loggers>
</configuration>