Java日志介绍-Log4j2

Posted 咏吟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java日志介绍-Log4j2相关的知识,希望对你有一定的参考价值。

Log4j2是Log4j的升级版,相比其前身Log4j 1.x提供了显著的改进,并提供了在Logback中提供的许多改进,同时修复了Logback体系结构中的一些固有问题。

Log4j2的内容很多,本文主要介绍其简单实用方法;文中所使用到的软件版本:Java 1.8.0_191、log4j 2.12.1。

1、配置

1.1、加载配置

Log4j2能够在初始化期间自动查找配置文件进行配置;按照优先级查找配置文件直到找到,优先级如下:

1、查找系统属性log4j.configurationFile对应的配置文件
2、在classpath下查找log4j2-test.properties
3、在classpath下查找log4j2-test.yaml或者log4j2-test.yml
4、在classpath下查找log4j2-test.json或者log4j2-test.jsn
5、在classpath下查找log4j2-test.xml
6、在classpath下查找log4j2.yaml或者log4j2.yml
7、在classpath下查找log4j2.json或者log4j2.jsn
8、在classpath下查找log4j2.xml
9、如果上面的步骤都找不到配置文件,则使用默认的配置,日志会输出到控制台。

1.2、自动更新配置

如果配置是从配置文件加载的,通过设置monitorInterval(单位为秒)参数,可以让log4j2自动检查文件的变化情况,如果变化了则从新加载配置。检查文件是否变化的时机为记录日志时且距离上次检查时间超过monitorInterval。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
...
</Configuration>

2、Appenders

2.1、ConsoleAppender

<Console name="STDOUT">
</Console>

输出日志到控制台,有如下常用参数:

filter 过滤器
layout 布局器
name 输出目的地名称
target SYSTEM_OUT或SYSTEM_ERR;默认为SYSTEM_OUT。

2.2、FileAppender

<File name="File" fileName="D:	empa.log">
</File>

输出日志到文件,有如下常用参数:

filter 过滤器
fileName 文件名称
layout 布局器
name 输出目的地名称

2.3、RollingFileAppender

<RollingFile name="RollingFile" fileName="D:	emp.log" filePattern="D:	emp$${date:yyyy-MM}-%d{MM-dd-yyyy}-%i.log">
</RollingFile>

滚动输出日志到文件,通过一定的策略来生成历史日志文件,并保留固定数量的最新历史文件;有如下常用参数:

filter 过滤器
fileName 文件名称
filePattern 历史日志文件名称生成策略,支持日期格式配置:$${date:yyyy-MM}、%d{MM-dd-yyyy};序号配置:%i
layout 布局器
name 输出目的地名称
policy 历史日志文件生成策略
DefaultRolloverStrategy 默认策略

2.3.1、policy

有如下策略:

<Policies>
  <OnStartupTriggeringPolicy />
  <SizeBasedTriggeringPolicy size="20MB" />
  <TimeBasedTriggeringPolicy />
</Policies>

OnStartupTriggeringPolicy,启动的时候就生成历史日志文件,其参数:

minSize 日志文件大于该值,启动时会生成历史日志文件;默认为1,防止空的日志文件生成历史日志文件

SizeBasedTriggeringPolicy,日志文件达到多大时就会生成历史日志文件,其参数:

size 日志文件大小

TimeBasedTriggeringPolicy,根据时间间隔来生成历史日志文件,其参数:

interval 生成新的历史日志文件的时间间隔,单位为小时,默认为1
modulate 是否应调整间隔,如间隔为4小时,当前时间为3点,则生成历史日志文件的时间点为4点、8点...
maxRandomDelay 随机延迟生成历史日志文件的最大秒数,默认为0;如果服务器上有多个应用程序且配置的滚动日志文件时间端一样,则此设置非常有用,可以将负载分散到不同时间。

SizeBasedTriggeringPolicy和TimeBasedTriggeringPolicy如果一起使用,则filePattern中需指定%i,否则会覆盖原有历史日志文件,因为SizeBasedTriggeringPolicy策略起作用时不会改变文件名中的时间戳

2.3.2、DefaultRolloverStrategy

有如下常用参数:

max 最大历史日志文件个数

 

还有其他好多Appender,如JDBCAppender、JMS Appender、JPAAppender、KafkaAppender等等,这里就不一一介绍,可以参考官网文档:https://logging.apache.org/log4j/2.x/manual/appenders.html

3、Layouts

log4j2提供了多种layout,如HTML Layout、JSON Layout、Pattern Layout、XML Layout等等,这里着重介绍Pattern Layout。

<PatternLayout pattern="%d %-p [%t] %C.%M[%F:%L] -> %m%n" />

Pattern Layout通过参数来格式化日志信息,与log4j 1.x中的用法很类似:

d{pattern}、date{pattern} 输出日志记录事件的日期,可以在其后指定格式;如:%d{dd MMM yyyy HH:mm:ss,SSS},输出类似:02 Nov 2012 14:34:02,781
p|level{level=label, level=label, ...}、p|level{length=n}、p|level{lowerCase=true|false} 输出日志记录事件的优先级,如:%level{WARN=W, INFO=I,length=2}
t、tn、thread、threadName 输出生成日志记录事件的线程的名称
T、id、threadId 输出生成日志记录事件的线程的id
c{precision}、logger{precision} 输出日志记录事件的类别;后面可以给出精度,如类别为"org.apache.commons.Foo";%c{1}将输出"Foo",%c{1.}将输出"o.a.c.Foo"
C{precision}、class{precision} 输出发出日志记录请求的调用方的完全限定类名称;后面可以给出精度,与c{precision}类似。
M、method 输出发出日志记录请求的方法名称。该操作代价较高,可能会影响性,小心使用。
F、file 输出发出日志记录请求的文件名。该操作代价较高,可能会影响性,小心使用。
L、line 输出发出日志记录请求的文件行号。该操作代价较高,可能会影响性,小心使用。
m{nolookups}{ansi}、msg{nolookups}{ansi}、message{nolookups}{ansi} 输出应用程序提供的消息
n 输出与平台相关的行分隔符,Windows平台为 ,Unix平台为
x、NDC 输出与生成日志记录事件的线程关联的NDC(嵌套诊断上下文)
X{key[,key2...]}、mdc{key[,key2...]}、MDC{key[,key2...]} 用于输出与生成日志记录事件的线程关联的MDC(映射诊断上下文)。通常用于多个客户端连接同一台服务器,方便服务器区分是哪个客户端访问留下来的日志。如%X{5}将记录代号为5的客户端的日志

默认情况下,相关信息会全部输出;可以借助格式修改器,更改最小字段宽度、最大字段宽度和对齐方向。格式修改器放置在百分比符号和转换字符之间。

%20c 如果类别名称少于20个字符,则用空格左垫。
%-20c 如果类别名称少于20个字符,则用空格右垫。
%.30c 如果类别名称长于30个字符,则从左开始截取掉多余的字符。
%20.30c 如果类别名称少于20个字符,则用空格左垫;如果类别名称长于30个字符,则从左开始截取掉多余的字符。
%-20.30c 如果类别名称少于20个字符,则用空格右垫;如果类别名称长于30个字符,则从左开始截取掉多余的字符。

更多相关说明参见 https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout

4、Lookups

lookup的主要功能就是提供另外一种方式以添加某些特殊的值到日志中。

<File name="lookupTest" fileName="D:	emplookup.log">
    <PatternLayout pattern="$${date:yyyy-MM} $${env:PATH} ${java:runtime} ${sys:file.encoding} %d -> %m%n" />
</File>

4.1、Date Lookup

获取当前日期的值,使用SimpleDateFormat验证格式是否有效;如获取当前日期月份:$${date:yyyy-MM}

4.2、Environment Lookup

获取环境变量的值;如获取$PATH变量的值:$${env:PATH}

4.3、Java Lookup

获取Java环境信息相关的值;如获取java运行时:${java:runtime}

4.4、System Properties Lookup

获取系统属性相关的值;如获取系统文件编码:${sys:file.encoding}

 

还有其他好多Lookup,如Context Map Lookup、Jndi Lookup、Spring Boot Lookup等等,这里就不一一介绍,可以参考官网文档:https://logging.apache.org/log4j/2.x/manual/lookups.html。

5、Filters

Filters用来确定日志是否被输出。过滤器包含两个基本参数,onMatch:匹配过滤器时执行的动作,onMismatch:不匹配过滤器时执行的动作;这两个参数的值可以为: ACCEPT、DENY 或NEUTRAL。ACCEPT表示输出日志;DENY表示不输出日志;NEUTRAL一般用于多个过滤器中,表示执行下一个过滤器。

在多个过滤器一起使用时:
如果一个过滤器配置为onMatch="ACCEPT"(或onMismatch="ACCEPT"),并且日志消息匹配onMatch(或匹配onMismatch),则输出该日志消息并忽略后面的过滤器;
如果一个过滤器配置为onMatch="DENY"(或onMismatch="DENY"),并且日志消息匹配onMatch(或匹配onMismatch),则不输出该日志消息并忽略后面的过滤器;
如果一个过滤器配置为onMatch="NEUTRAL"(或onMismatch="NEUTRAL"),并且日志消息匹配onMatch(或匹配onMismatch),则继续执行后面的过滤器。

<Filters>
	<RegexFilter regex="This.*" onMatch="NEUTRAL" onMismatch="DENY"/>
	<ThresholdFilter level="INFO" onMatch="NEUTRAL" onMismatch="DENY"/>
	<TimeFilter start="05:00:00" end="17:30:00" onMatch="NEUTRAL" onMismatch="DENY"/>    
</Filters>

5.1、RegexFilter

通过java正则表达式来与日志消息来比较,判断是否过滤。

5.2、ThresholdFilter

通过日志级别来判断是否过滤

5.3、TimeFilter

通过时间来判断是否过滤

5.4、CompositeFilter

组合过滤器,通过组合其他的过滤器来组成一个过滤链。

 

还有其他各种Filter,如BurstFilter、MarkerFilter等等,这里就不一一介绍,可以参考官网文档:https://logging.apache.org/log4j/2.x/manual/filters.html。

6、实际使用

6.1、配置文件log4j2.xml

该文件放到src或src/main/resources(spring boot工程)下即可。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" strict="true" monitorInterval="30">
    <Appenders>
        <Console name="STDOUT">
            <PatternLayout pattern="%d %p [%t] %C.%M[%F:%L] -> %m%n" />
            <Filters>
                <RegexFilter regex="This.*" onMatch="NEUTRAL" onMismatch="DENY"/>
                <ThresholdFilter level="INFO" onMatch="NEUTRAL" onMismatch="DENY"/>
                <TimeFilter start="05:00:00" end="17:30:00" onMatch="NEUTRAL" onMismatch="DENY"/>    
            </Filters>
        </Console>
        <File name="File" fileName="D:	empa.log">
            <PatternLayout pattern="%d %-p [%t] %C.%M[%F:%L] -> %m%n" />
        </File>
        <File name="lookupTest" fileName="D:	emplookup.log">
            <PatternLayout pattern="$${date:yyyy-MM} $${env:PATH} ${java:runtime} ${sys:file.encoding} %d -> %m%n" />
        </File>
        <RollingFile name="RollingFile" fileName="D:	emp.log" filePattern="D:	emp$${date:yyyy-MM}-%d{MM-dd-yyyy}-%i.log">
            <PatternLayout pattern="%d %-p [%t] %C.%M[%F:%L] -> %m%n" />
            <Policies>
                <OnStartupTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="200KB" />
                <TimeBasedTriggeringPolicy />
            </Policies>
            <DefaultRolloverStrategy max="5"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="STDOUT" />
            <AppenderRef ref="File" />
            <AppenderRef ref="lookupTest" />
            <AppenderRef ref="RollingFile" />
        </Root>
        <!-- Logger name="com.inspur" level="info"> <AppenderRef ref="File"/> </Logger -->
    </Loggers>
</Configuration>

6.2、代码例子

package com.inspur.demo.log;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


/**
 * log4j2使用示例
 */
public class Log4j2Case {
    private static Logger logger = LogManager.getLogger(Log4j2Case.class);
    public static void main(String[] args) throws Exception {
        logger.debug("This is debug message.");
        logger.warn(logger.getClass());
        for (int i = 0; i < 100; i++) {
            logger.info("This is info message:" + i);
        }
    }
}

运行代码可以看到控制台及相关的文件中生成了日志消息。

以上是关于Java日志介绍-Log4j2的主要内容,如果未能解决你的问题,请参考以下文章

Java学习-007-Log4J 日志记录配置文件详解及实例源代码

Java日志介绍-Log4j

Java日志

Java日志框架学习--JUL和Log4j--上

Java接口自动化之log4j日志框架

Java 13学习笔记53使用Log4j