log4j2
简介
log4j2是log4j 1.x 的升级版,2015年5月,Apache宣布log4j1.x 停止更新, 最后版本为1.2.17。
log4j2参考了logback的一些优秀的设计,并且修复了一些问题,因此带来了一些重大的提升,主要有:
- 异常处理:在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制
- 性能提升:log4j2相较于log4j 1和logback都具有很明显的性能提升
- 自动重载配置:参考logback设计,支持自动刷新参数,可以动态修改日志级别,而不重启应用
- 无垃圾机制: 大部分情况下,都可以使用其无垃圾机制,避免频繁的日志收集导致的jvm gc
版本
在官网的下载页(https://logging.apache.org/log4j/2.x/download.html),有提示支持各jdk大版本的最后log4j版本
案例
创建项目
创建一个空的maven项目,结构如图:
配置项目
添加依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j2.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2.version}</version>
</dependency>
我这里使用的版本为2.14.0
添加log4j2配置
在src/main/resources下,创建文件log4j2.xml,注意名字不要变:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error" monitorinterval="5">
<!--先定义所有的appender -->
<appenders>
<!--这个输出控制台的配置 -->
<Console name="Console" target="SYSTEM_OUT">
<!-- 控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch) -->
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
<!-- 这个都知道是输出日志的格式 -->
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</Console>
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 -->
<!--append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true -->
<File name="log" fileName="D:/logs/log4j2.log" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!--添加过滤器ThresholdFilter,可以有选择的输出某个级别以上的类别 onMatch="ACCEPT" onMismatch="DENY"意思是匹配就接受,否则直接拒绝 -->
<File name="ERROR" fileName="D:/logs/error.log">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%d{yyyy.MM.dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!--这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
<RollingFile name="RollingFile" fileName="D:/logs/web.log"
filePattern="logs/$${date:yyyy-MM}/web-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/>
<SizeBasedTriggeringPolicy size="2MB"/>
</RollingFile>
</appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效 -->
<loggers>
<root level="trace">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
<appender-ref ref="ERROR"/>
<appender-ref ref="log"/>
</root>
</loggers>
</configuration>
先这样使用,后面再做详解
创建测试类
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4j2Test {
private static Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
// trace level
logger.trace("trace log ...");
// debug level
logger.debug("debug log ...");
// info level
logger.info("info log ...");
// error level
logger.error("error log ...");
}
}
}
运行测试
运行项目,控制台输出:
用法
简介
log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本常用.xml后缀的文件进行配置,除此之外还包含.json和.jsn配置文件
log4j2虽然采用xml风格进行配置,依然包含三个组件,分别是 Logger(记录器)、Appender(输出目的地)、Layout(日志布局)。
配置文件
根节点
根节点Configuration有两个属性:
- status: 指定log4j2本身的日志级别, 包括"trace", "debug", "info", "warn", "error" and "fatal"
- monitorinterval: log4j 2.x的新特点,自动重载配置。指定自动重新配置的监测间隔时间,单位是s, 最小是5s
有两个子节点(表明可以定义多个Appender和Logger)
- Appenders: 输出源,用于定义日志输出的地方。
- Loggers: 日志器
Appenders节点
详见官网: https://logging.apache.org/log4j/2.x/manual/appenders.html
log4j2支持的输出源有很多,有控制台Console、文件File、RollingRandomAccessFile、MongoDB、Flume 等
- Console:控制台输出源是将日志打印到控制台上,开发的时候一般都会配置,以便调试
- File:文件输出源,用于将日志写入到指定的文件,需要配置输入到哪个位置(例如:D:/logs/mylog.log)
- RollingRandomAccessFile: 该输出源也是写入到文件,不同的是比File更加强大,可以指定当文件达到一定大小(如20MB)时,另起一个文件继续写入日志,另起一个文件就涉及到新文件的名字命名规则,因此需要配置文件命名规则
这种方式更加实用,因为你不可能一直往一个文件中写,如果一直写,文件过大,打开就会卡死,也不便于查找日志。- fileName 指定当前日志文件的位置和文件名称
- filePattern 指定当发生Rolling时,文件的转移和重命名规则
- SizeBasedTriggeringPolicy 指定当文件体积大于size指定的值时,触发Rolling
- DefaultRolloverStrategy 指定最多保存的文件个数
- TimeBasedTriggeringPolicy 这个配置需要和filePattern结合使用,注意filePattern中配置的文件重命名规则是${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i,最小的时间粒度是mm,即分钟
- TimeBasedTriggeringPolicy指定的size是1,结合起来就是每1分钟生成一个新文件。如果改成%d{yyyy-MM-dd HH},最小粒度为小时,则每一个小时生成一个文件
- NoSql:MongoDb, 输出到MongDb数据库中
- Flume:输出到Apache Flume(Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。)
- Async:异步,需要通过AppenderRef来指定要对哪种输出源进行异步(一般用于配置RollingRandomAccessFile)
常见的有三种子节点:
- Console: 定义输出到控制台的Appender
- File: 定义输出到指定位置的文件的Appender
- RollingFile: 定义超过指定大小自动删除旧的创建新的的Appender
通过在子节点中加入
配置 | 含义 |
---|---|
%m | 输出代码指定信息,如info(“message”),输出message |
%c | 输出所属类的全名, Num为类名输出的范围 如"com.sun.aaa.classB",%c{2}将使日志输出输出范围为:aaa.classB |
%d | 输出日志时间其格式为 可指定格式 如 %d{HH:mm:ss.SSS},输出到毫秒 |
%-5level | 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补齐空格 |
%L | 输出行号 |
%l | 输出日志事件发生位置,包括类名、方法名、文件名、行数 |
%F | 输出所在的类文件名,如Log4j2Test.java |
%M | 输出所在方法名 |
%t | 输出产生该日志事件的线程名 |
%r | 输出从启动到显示该条日志信息所耗费的时间(ms) |
%logger | 输出logger名称。Root Logger因为没有名称,所以不会输出 |
%p | 输出日志的优先级,即 FATAL ,ERROR 等 |
%n | 换行符 |
Loggers节点
日志器分根日志器Root和自定义日志器。
当根据日志名字(Appender)获取不到指定的日志器时,就使用Root作为默认的日志器。
- Root: 用来指定项目的根日志,如果没有单独指定Logger,那么就会默认使用该Root日志输出
- Logger: 用来单独指定日志的形式,需要指定:
- Logger的名称(name)。对于命名可以以包名作为日志的名字,不同的包配置不同的级别等
- 日志级别(level): TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF,不指定时level默认为ERROR
- 相加性(additivity):是否同时输出log到父类的appender,缺省为true。 对于一般的日志器(如Console、File、RollingRandomAccessFile),一般需要配置一个或多个输出源AppenderRef;