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是必须的,其他包根据需要引入,如下图所示:
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>