轻松搞懂log4j2配置!

elltor 2020年06月08日 102次浏览

[toc]

入门

百度百科

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
    • 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中配置的文件重命名规则是$-%d-%i,最小的时间粒度是mm,即分钟
        TimeBasedTriggeringPolicy指定的size是1,结合起来就是每1分钟生成一个新文件。如果改成%d
        ,最小粒度为小时,则每一个小时生成一个文polic件
  • NoSql:MongoDb, 输出到MongDb数据库中

  • Flume:输出到Apache Flume(Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。)

  • Async:异步,需要通过AppenderRef来指定要对哪种输出源进行异步(一般用于配置RollingRandomAccessFile)

下面配置了两个输出源ConsoleRollingRandomAccessFIle,第一个是打印到控制台,第二个是输出到文件(当日志文件达到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的自定义r日志了! 对了springboot目前默认的是logback日志工具, 不过配置几乎差不多.