轻松搞懂 Log4j2 配置
入门
百度百科
Log4j 是 Apache 的一个开源项目,通过使用 Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI 组件,甚至是套接口服务器、NT 的事件记录器、UNIX Syslog 守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
log4j 工作流程
log4j 的三个重要组成: Logger(日志产生), Layout(格式化), Appender(日志输出) 在这个过程中,logger 是日志的产生源,appender 负责把产生的日志输入到各个目的地(console/file/database…),layout 负责格式化日志。
maven 依赖
<!--log4j2jar-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
<!--log4j2的slf4j实现-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
</dependency>
log4j2 展示(简单了解即可)
log4j2 配置文件可以有多种 xml、yaml、json 等。 项目中常用的是 xml。在 xml 方式配置中又分为严格模式和非严格模式
非严格模式示例
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
严格模式示例
<?xml version="1.0" encoding="UTF-8"?>;
<Configuration>
<Properties>
<Property name="name1">value</property>
<Property name="name2" value="value2"/>
</Properties>
<Filter type="type" ... />
<Appenders>
<Appender type="type" name="name">
<Filter type="type" ... />
</Appender>
...
</Appenders>
<Loggers>
<Logger name="name1">
<Filter type="type" ... />
</Logger>
...
<Root level="level">
<AppenderRef ref="name"/>
</Root>
</Loggers>
</Configuration>
区别: 严格模式中 Appender 的类型是通过属性表示的(<Appender type="Console" name="STDOUT">
),非严格模式 Appender 类型是通过标签表示的( <Console name="Console" target="SYSTEM_OUT">
), 这是比较明显的区别之一, 当然不止这一点.
xml 配置文件标签及属性(重要)
==以下为非严格配置==
配置文件结构
- Configuration
- properties
- Appenders
- Console
- PatternLayout
- File
- RollingRandomAccessFile
- Async
- Console
- Loggers
- Logger
- AppenderRef
- Filter
- Root
- AppenderRef
- Filter
- Logger
Configuration : 根配置标签
- status的值有 “trace”, “debug”, “info”, “warn”, “error” and “fatal”,用于控制 log4j2 日志框架本身的日志级别,如果将 stratus
- 设置为较低的级别就会看到很多关于 log4j2 本身的日志,如加载 log4j2 配置文件的路径等信息 monitorInterval,含义是每隔多少秒重新读取配置文件,可以不重启应用的情况下修改配置
Appenders:输出源,用于定义日志输出的地方
-
Console : 控制台输出源是将日志打印到控制台上,开发的时候一般都会配置,以便调试,log4j2 支持的输出源有很多,除了 Console 还有:文件 File、RollingRandomAccessFile、MongoDB、Flume 等
-
File :文件输出源,用于将日志写入到指定的文件,需要配置输入到哪个位置(例如:D:/logs/mylog.log)
-
RollingRandomAccessFile : 该输出源也是写入到文件,不同的是比 File 更加强大,可以指定当文件达到一定大小(如 20MB)时,另起一个文件继续写入日志,另起一个文件就涉及到新文件的名字命名规则,因此需要配置文件命名规则 这种方式更加实用,因为你不可能一直往一个文件中写,如果一直写,文件过大,打开就会卡死,也不便于查找日志。
- fileName 指定当前日志文件的位置和文件名称
- filePattern 指定当发生 Rolling 时,文件的转移和重命名规则
- SizeBasedTriggeringPolicy 指定当文件体积大于 size 指定的值时,触发 Rolling
- Policies
- DefaultRolloverStrategy 指定最多保存的文件个数
- TimeBasedTriggeringPolicy 这个配置需要和 filePattern 结合使用,注意 filePattern 中配置的文件重命名规则是${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i,最小的时间粒度是 mm,即分钟 TimeBasedTriggeringPolicy 指定的 size 是 1,结合起来就是每 1 分钟生成一个新文件。如果改成%d{yyyy-MM-dd HH},最小粒度为小时,则每一个小时生成一个文 polic 件
-
NoSql:MongoDb, 输出到 MongDb 数据库中
-
Flume:输出到 Apache Flume(Flume 是 Cloudera 提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume 支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume 提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。)
-
Async:异步,需要通过 AppenderRef 来指定要对哪种输出源进行异步(一般用于配置 RollingRandomAccessFile)
下面配置了两个输出源Console
和RollingRandomAccessFIle
,第一个是打印到控制台,第二个是输出到文件(当日志文件达到 20M 就会被分割存储到单独文件)
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %m%n" />
</Console>
<RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
<PatternLayout pattern="%d %p %c{1.} [%t] - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
<DefaultRolloverStrategy max="10"/>
</RollingRandomAccessFile>
</Appenders>
Loggers :日志器, 日志产生源 日志器分: 根日志器 Root和自定义日志器 Logger,当根据日志名字获取不到指定的日志器时就使用 Root 作为默认的日志器,自定义时需要指定每个 Logger 的名称 name(对于命名可以以包名作为日志的名字,不同的包配置不同的级别等),日志级别 level,相加性 additivity(是否继承下面配置的日志器), 对于一般的日志器(如 Console、File、RollingRandomAccessFile)一般需要配置一个或多个输出源 AppenderRef; 下面这个例子中有两个产生源 Root 和 UserController 类的 Logger,在产生源上可以设日志过滤等级(All < Trace < Debug < Info < Warn < Error < Fatal < OFF),all 会显示所有日志,info 则只显示大于等于 info 的日志。
<Loggers>
<Root level="all">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingRandomAccessFile" />
</Root>
<Logger name="com.marchsoft.controller.UserController" level="info" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingRandomAccessFile" />
</Logger>
</Loggers>
Filter Filter 用于过滤一些日志信息,Filter 在过滤每一条日志时都会返回一个值 ACCEPT、 DENY 或者 NEUTRAL。 不同的 Filter 的有不同的用处,BrustFilter 用于防止日志流量过大,还可以使用 DynamicThresholdFilter 根据属性来过滤特定级别的日志。可以根据具体的需要选择相应的 Filter
properties : 自定义属性, 一遍再其他地方引用, 引用方式为${自定义属性}
<!-- 定义 -->
<properties>
<property name="LOG_HOME">D:/logs</property>
<property name="FILE_NAME">mylog.txt</property>
</properties>
<!--使用, 在fileName属性中引用-->
<RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}".../>
PatternLayout 中的 pattern 属性正则参数属性
%d 表示时间,默认情况下表示打印完整时间戳 2012-11-02 14:34:02,123,可以调整 %d 后面的参数来调整输出的时间格式
%p 表示输出日志的等级,可以使用 %highlight{%p} 来高亮显示日志级别
%c 用来输出类名,默认输出的是完整的包名和类名,%c{1.} 输出包名的首字母和完整类名
%t 表示线程名称
%m 表示日志内容,%M 表示方法名称
%n 表示换行符
%L 表示打印日志的代码行数
level日志过滤级别参数 All < Trace < Debug < Info < Warn < Error < Fatal < OFF
- 越靠后级别越高
- 设值相应级别, 只显示该级别及更高级别的日志,例如:info,只显示 Info < Warn < Error < Fatal < OFF
使用 Slf4j
maven 依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
</dependency>
使用示例,在项目中使用时 logger 应该被定义成static
的成员变量。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Slf4jDemo {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Slf4jDemo.class);
logger.info("Slf4j log info");
}
}
完整配置示例
<?xml version="1.0" encoding="UTF-8"?>
<!--根配置标签-->
<!--Configuration标签至少要指定status标签, status指定的为缺省日志显示等级-->
<Configuration status="WARN">
<!--自定义属性通过${}来引用, 用自定已属性时为了方便同意管理-->
<properties>
<property name="LOG_HOME">D:/logs</property>
<property name="FILE_NAME">mylog.txt</property>
</properties>
<!--日志输出端, 可以时Console, File, RollingFile, RollingRandomAccessFile等等-->
<!--Rolling开头的输出端具有文本分割功能,可以按照时间(TimeBasedTriggeringPolicy)或者文件大小(SizeBasedTriggeringPolicy)进行分割-->
<!--RollingRandomAccessFileRollingRandomAccessFile 与 RollingFile 在功能上基本一致,但是底层的实现有所区别,RollingFileAppender 底层是 BufferedOutputStream,
RollingRandomAccessFileAppender 底层是使用 ByteBuffer + RandomAccessFile ,性能上有了很大的提升。-->
<Appenders>
<!--此处name为Console指定一个名称(可任意), target指定输出源名称(非任意)-->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %m%n" />
</Console>
<!--name指定名称, fileName日志文件路径名称, filePattern分割日志路径名称, pattern日志内容的格式-->
<!--该Appender每天建一个日志分割文件夹,当mylog.txt文件达到20M,会将的内容转移到分割文件,此时mylog.txt中不会有之前的2M内容-->
<RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}"
filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
<PatternLayout pattern="%d %p %c{1.} [%t] - %m%n"/>
<Policies>
<!--interval日志颗粒度, 与filePattern有关联, 时间HH-mm颗粒度为分中, 时间HH颗粒度为消息, 时间yyy-MM-dd为天-->
<!-- <TimeBasedTriggeringPolicy interval="1"/>-->
<!--size文件大小, 达到时对日志进行分割, 单位有MB、KB-->
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
<!--最大分割数量-->
<DefaultRolloverStrategy max="10"/>
</RollingRandomAccessFile>
</Appenders>
<!--日志器,产生日志-->
<Loggers>
<!--level日志输出级别-->
<Root level="all">
<!--指定该日志器输出的Appender, 此处对对控制台和文件进行输出-->
<AppenderRef ref="Console" />
<AppenderRef ref="RollingRandomAccessFile" />
</Root>
<Logger name="com.marchsoft.controller.UserController" level="all" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingRandomAccessFile" />
</Logger>
</Loggers>
</Configuration>
测试
本文到这里就完了, 你搞懂了吗? 搞懂你就可以去自定义 springboot 的自定义日志了,对了 springboot 目前默认的是 logback 日志工具, 不过配置几乎差不多.
(完)