Kymotz's Blog

轻松搞懂Log4j2配置

#Log4j #教程

入门

百度百科

Log4j 是 Apache 的一个开源项目,通过使用 Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI 组件,甚至是套接口服务器、NT 的事件记录器、UNIX Syslog 守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

log4j 工作流程

log4j 的三个重要组成: Logger(日志产生), Layout(格式化), Appender(日志输出) 在这个过程中,logger 是日志的产生源,appender 负责把产生的日志输入到各个目的地(console/file/database…),layout 负责格式化日志。

maven 依赖

 1	<!--log4j2jar-->
 2    <dependency>
 3        <groupId>org.apache.logging.log4j</groupId>
 4        <artifactId>log4j-api</artifactId>
 5        <version>2.12.1</version>
 6    </dependency>
 7    <dependency>
 8        <groupId>org.apache.logging.log4j</groupId>
 9        <artifactId>log4j-core</artifactId>
10        <version>2.12.1</version>
11    </dependency>
12    <!--log4j2的slf4j实现-->
13     <dependency>
14        <groupId>org.apache.logging.log4j</groupId>
15        <artifactId>log4j-slf4j-impl</artifactId>
16        <version>2.12.1</version>
17    </dependency>

log4j2 展示(简单了解即可)

log4j2 配置文件可以有多种 xml、yaml、json 等。 项目中常用的是 xml。在 xml 方式配置中又分为严格模式和非严格模式

非严格模式示例

 1<?xml version="1.0" encoding="UTF-8"?>
 2<Configuration status="WARN">
 3  <Appenders>
 4    <Console name="Console" target="SYSTEM_OUT">
 5      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
 6    </Console>
 7  </Appenders>
 8  <Loggers>
 9    <Root level="error">
10      <AppenderRef ref="Console"/>
11    </Root>
12  </Loggers>
13</Configuration>

严格模式示例

 1<?xml version="1.0" encoding="UTF-8"?>;
 2<Configuration>
 3  <Properties>
 4    <Property name="name1">value</property>
 5    <Property name="name2" value="value2"/>
 6  </Properties>
 7  <Filter type="type" ... />
 8  <Appenders>
 9    <Appender type="type" name="name">
10      <Filter type="type" ... />
11    </Appender>
12    ...
13  </Appenders>
14  <Loggers>
15    <Logger name="name1">
16      <Filter type="type" ... />
17    </Logger>
18    ...
19    <Root level="level">
20      <AppenderRef ref="name"/>
21    </Root>
22  </Loggers>
23</Configuration>

区别: 严格模式中 Appender 的类型是通过属性表示的(<Appender type="Console" name="STDOUT">),非严格模式 Appender 类型是通过标签表示的( <Console name="Console" target="SYSTEM_OUT">), 这是比较明显的区别之一, 当然不止这一点.

xml 配置文件标签及属性(重要)

==以下为非严格配置==

配置文件结构

  • Configuration
    • properties
    • Appenders
      • Console
        • PatternLayout
      • File
      • RollingRandomAccessFile
      • Async
    • Loggers
      • Logger
        • AppenderRef
        • Filter
      • Root
        • AppenderRef
        • Filter

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)

下面配置了两个输出源ConsoleRollingRandomAccessFIle,第一个是打印到控制台,第二个是输出到文件(当日志文件达到 20M 就会被分割存储到单独文件)

 1    <Appenders>
 2        <Console name="Console" target="SYSTEM_OUT">
 3            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %m%n" />
 4        </Console>
 5        <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}"
 6                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
 7            <PatternLayout pattern="%d %p %c{1.} [%t] - %m%n"/>
 8            <Policies>
 9                <TimeBasedTriggeringPolicy />
10                <SizeBasedTriggeringPolicy size="20 MB"/>
11            </Policies>
12            <DefaultRolloverStrategy max="10"/>
13        </RollingRandomAccessFile>
14    </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 的日志

 1    <Loggers>
 2        <Root level="all">
 3            <AppenderRef ref="Console" />
 4            <AppenderRef ref="RollingRandomAccessFile" />
 5        </Root>
 6        <Logger name="com.marchsoft.controller.UserController" level="info" additivity="false">
 7            <AppenderRef ref="Console" />
 8            <AppenderRef ref="RollingRandomAccessFile" />
 9        </Logger>
10    </Loggers>

Filter Filter 用于过滤一些日志信息,Filter 在过滤每一条日志时都会返回一个值 ACCEPT、 DENY 或者 NEUTRAL。 不同的 Filter 的有不同的用处,BrustFilter 用于防止日志流量过大,还可以使用 DynamicThresholdFilter 根据属性来过滤特定级别的日志。可以根据具体的需要选择相应的 Filter

properties : 自定义属性, 一遍再其他地方引用, 引用方式为${自定义属性}

1	<!-- 定义 -->
2    <properties>
3        <property name="LOG_HOME">D:/logs</property>
4        <property name="FILE_NAME">mylog.txt</property>
5    </properties>
6
7	<!--使用, 在fileName属性中引用-->
8	<RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}".../>

PatternLayout 中的 pattern 属性正则参数属性

1%d 表示时间,默认情况下表示打印完整时间戳 2012-11-02 14:34:02,123,可以调整 %d 后面的参数来调整输出的时间格式
2%p 表示输出日志的等级,可以使用 %highlight{%p} 来高亮显示日志级别
3%c 用来输出类名,默认输出的是完整的包名和类名,%c{1.} 输出包名的首字母和完整类名
4%t 表示线程名称
5%m 表示日志内容,%M 表示方法名称
6%n 表示换行符
7%L 表示打印日志的代码行数

level日志过滤级别参数 All < Trace < Debug < Info < Warn < Error < Fatal < OFF

  • 越靠后级别越高
  • 设值相应级别, 只显示该级别及更高级别的日志,例如:info,只显示 Info < Warn < Error < Fatal < OFF

使用 Slf4j

maven 依赖

1<dependency>
2     <groupId>org.apache.logging.log4j</groupId>
3     <artifactId>log4j-slf4j-impl</artifactId>
4     <version>2.12.1</version>
5</dependency>

使用示例,在项目中使用时 logger 应该被定义成static的成员变量。

1import org.slf4j.Logger;
2import org.slf4j.LoggerFactory;
3public class Slf4jDemo {
4    public static void main(String[] args) {
5        Logger logger = LoggerFactory.getLogger(Slf4jDemo.class);
6
7        logger.info("Slf4j log info");
8    }
9}

完整配置示例

 1<?xml version="1.0" encoding="UTF-8"?>
 2<!--根配置标签-->
 3<!--Configuration标签至少要指定status标签, status指定的为缺省日志显示等级-->
 4<Configuration status="WARN">
 5    <!--自定义属性通过${}来引用, 用自定已属性时为了方便同意管理-->
 6    <properties>
 7        <property name="LOG_HOME">D:/logs</property>
 8        <property name="FILE_NAME">mylog.txt</property>
 9    </properties>
10
11    <!--日志输出端, 可以时Console, File, RollingFile, RollingRandomAccessFile等等-->
12    <!--Rolling开头的输出端具有文本分割功能,可以按照时间(TimeBasedTriggeringPolicy)或者文件大小(SizeBasedTriggeringPolicy)进行分割-->
13    <!--RollingRandomAccessFileRollingRandomAccessFile 与 RollingFile 在功能上基本一致,但是底层的实现有所区别,RollingFileAppender 底层是 BufferedOutputStream,
14    RollingRandomAccessFileAppender 底层是使用 ByteBuffer + RandomAccessFile ,性能上有了很大的提升。-->
15    <Appenders>
16        <!--此处name为Console指定一个名称(可任意), target指定输出源名称(非任意)-->
17        <Console name="Console" target="SYSTEM_OUT">
18            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %m%n" />
19        </Console>
20        <!--name指定名称, fileName日志文件路径名称, filePattern分割日志路径名称, pattern日志内容的格式-->
21        <!--该Appender每天建一个日志分割文件夹,当mylog.txt文件达到20M,会将的内容转移到分割文件,此时mylog.txt中不会有之前的2M内容-->
22        <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}"
23                     filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
24            <PatternLayout pattern="%d %p %c{1.} [%t] - %m%n"/>
25            <Policies>
26                <!--interval日志颗粒度, 与filePattern有关联, 时间HH-mm颗粒度为分中, 时间HH颗粒度为消息, 时间yyy-MM-dd为天-->
27<!--                <TimeBasedTriggeringPolicy interval="1"/>-->
28                <!--size文件大小, 达到时对日志进行分割, 单位有MB、KB-->
29                <SizeBasedTriggeringPolicy size="20 MB"/>
30            </Policies>
31            <!--最大分割数量-->
32            <DefaultRolloverStrategy max="10"/>
33        </RollingRandomAccessFile>
34    </Appenders>
35    <!--日志器,产生日志-->
36    <Loggers>
37        <!--level日志输出级别-->
38        <Root level="all">
39            <!--指定该日志器输出的Appender, 此处对对控制台和文件进行输出-->
40            <AppenderRef ref="Console" />
41            <AppenderRef ref="RollingRandomAccessFile" />
42        </Root>
43
44        <Logger name="com.marchsoft.controller.UserController" level="all" additivity="false">
45            <AppenderRef ref="Console" />
46            <AppenderRef ref="RollingRandomAccessFile" />
47        </Logger>
48    </Loggers>
49</Configuration>

测试

在这里插入图片描述
在这里插入图片描述

本文到这里就完了, 你搞懂了吗? 搞懂你就可以去自定义 springboot 的自定义日志了,对了 springboot 目前默认的是 logback 日志工具, 不过配置几乎差不多.

(完)


Top↑
comments powered by Disqus