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版本

image-20210112144330710

案例

创建项目

创建一个空的maven项目,结构如图:
image-20210112103447378

配置项目

添加依赖

<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 ...");
        }
    }
}

运行测试

运行项目,控制台输出:
image-20210112103819043

用法

简介

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;
posted @ 2022-12-29 22:15  水木夏  阅读(94)  评论(0编辑  收藏  举报