log4j2 入门教程

log4j2 中4是和for谐音,j是Java的意思,2是第二代,即log4j2是log4j1.x的升级版,大概在2014年开始发行release版本,号称比log4j 1.x 在多线程下具有更高的性能,当然相比于log4j 1.x,使用更加方便。

1、添加配置

使用log4j 2 需要加载的jar包有

log4j-api-2.8.2.jar
log4j-core-2.8.2.jar

Maven项目中pom.xml中添加:

1.	<dependencies>
2.	<dependency>
3.	<groupId>org.apache.logging.log4j</groupId>
4.	<artifactId>log4j-api</artifactId>
5.	<version>2.8.2</version>
6.	</dependency>
7.	<dependency>
8.	<groupId>org.apache.logging.log4j</groupId>
9.	<artifactId>log4j-core</artifactId>
10.	<version>2.8.2</version>
11.	</dependency>
12.	</dependencies>

gradle项目中添加如下:

1.	dependencies {
2.	compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.8.2'
3.	compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.8.2'
4.	}

举个栗子:

1、最简单的代码:

public static void main(String[] args) {
    Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
    logger.trace("trace level");
    logger.debug("debug level");
    logger.info("info level");
    logger.error("error level");
    logger.fatal("fatal level");
}

执行上述代码,输出如下提示:

ERRORStatusLogger No log4j2 configuration file found. Using default configuration:logging only errors to the console. Set system property 'org.apache.logging.log4j.simplelog.StatusLogger.level'to TRACE to show Log4j2 internal initialization logging.

09:55:36.256 [main] ERROR  - error level

09:55:36.303 [main] FATAL  - fatal level

提示说找不到log4j2的配置文件文件,将使用缺省配置:控制台log的级别为error。log自身的日志级别为trace。(log4j2默认会在classpath目录下寻找log4j.json、log4j.jsn、log4j2.xml等名称的配置文件,如果都没有找到,则会按默认配置输出,也就是输出到控制台。)

补充日志级别的等级如下:

日志级别从低到高分别为:trace<debug<info<warn<error<fatal

如果设置为info,则低于info的信息都不会输出的,只有高于info的信息会输出。

2、添加 log4j2.xml文件之后:

log4j2.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>

再次执行之前的java代码,发现没有报提示说找不到配置文件。

分析配置:

在配置文件中,主要有两类,一类是Appenders(定义输出源),另一类是Loggers(定义打log的类型)。

输出格式:
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />

%d{HH:mm:ss.SSS}: 表示打log时的时间毫秒

[%t]:输出当前线程名称

%-5level:输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0

%logger{36}:输出logger名称,因为Root Logger没有名称,所以没有输出

%msg:日志文本

%n:换行

其他常用的占位符有:

%F:输出所在的类文件名,如:Tim.java

%L:输出行号

%M:输出所在方法名

%l:输出语句所在的行数,包括类名、方法名、文件名、行数

3、添加自定义Appender

<?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>
        <File name="TimFile" fileName="D:/logs/tim.log">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </File>
    </Appenders>
    <Loggers>
        <Logger name="timlog" level="trace" additivity="true">
            <AppenderRef ref="TimFile" />
        </Logger>
        <Root level="error">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

这里新增加了一个类型为File的appender,以及增加了一个新的logger。这里additivity=true,表示会将当前的logger特性会传递给Root,即上述的效果为即会在文件中输出log,也会传递给root的控制台输出log。

4、按分钟生成日志,每天日志过大则拆分

需求如下:

每天生成一个日志文件,但是如果一天内的日志文件体积超过1G,就重新生成一个文件。

需要使用到RollingRandomAccessFile Appender。配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="300">
    <properties>
        <property name="LOG_HOME">D:/logs</property>
        <property name="FILE_NAME">tim</property>
    </properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
        <RollingRandomAccessFile name="TimFile" fileName="${LOG_HOME}/${FILE_NAME}.log"
        filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
        <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        <Policies>
            <TimeBasedTriggeringPolicy interval="1" />
            <SizeBasedTriggeringPolicy size="1024 MB" />
        </Policies>
        <DefaultRolloverStrategy max="20" />
    </RollingRandomAccessFile>

</Appenders>
    <Loggers>
        <Logger name="timlog" level="trace" additivity="false">
            <AppenderRef ref="TimFile" />
        </Logger>
        <Root level="error">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

分析:

<properties>
    <property name="LOG_HOME">D:/logs</property>
    <property name="FILE_NAME">tim</property>
</properties>

定义两个常量便于后面使用。

RollingRandomAccessFile中的配置解释如下:

name:指定appender的名字。

fileName:指定当前日志文件的位置和文件名称。

filePattern:指定当发生Rolling时,文件的转移重命名规则
fileName="${LOG_HOME}/${FILE_NAME}.log"
        filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">

${LOG_HOME}/${FILE_NAME}.log是正在打印的日志的名称。

${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-ddHH-mm}-%i.log

是文件转移后的日志命名规则。

TimeBasedTriggeringPolicy:这个配置要和filePattern结合使用,比如:filePattern中的命名规则是${FILE_NAME}-%d{yyyy-MM-ddHH-mm}-%i,最小的时间粒度是mm,即分钟,而TimeBasedTriggeringPolicy指定的size是1,结合起来就是每1分钟生成一个新文件。同理,如果要每个小时生成一个文件,则改成%d{yyyy-MM-dd HH},最小粒度为小时

SizeBasedTriggerPolicy:指定当文件体积大于size指定的值是,触发Rolling。

DefaultRolloverStrategy:指定最多保存的文件个数。

5、按日志级别输出文件

一个好的打日志习惯:打日志的时候,一定要将不同等级的日志分文件打log,不要将所有级别的日志都打印在一个文件中,使得后期排查错误麻烦。比如:应该将error级别的日志单独打印在一个文件中。

举个栗子:

分别配置info级别输出到info.log文件中,error级别输出到error.log文件中,fatal级别输出到fatal.log文件中。

ps:各个级别的关系:off > fatal > error > warn > info > debug> trace > all

log4j2.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="300">
    <properties>
        <property name="LOG_HOME">D:/logs</property>
        <property name="FILE_NAME">tim</property>
    </properties>
    <Appenders>

        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>

        <RollingRandomAccessFile name="InfoFile"
        fileName="${LOG_HOME}/info.log"
        filePattern="${LOG_HOME}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd HH-mm}-%i.log">
            <Filters>
                <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        <PatternLayout
                pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        <Policies>
            <TimeBasedTriggeringPolicy interval="1" />
            <SizeBasedTriggeringPolicy size="10 MB" />
        </Policies>
        <DefaultRolloverStrategy max="20" />
        </RollingRandomAccessFile>

        <RollingRandomAccessFile name="ErrorFile"
                                 fileName="${LOG_HOME}/error.log"
                                 filePattern="${LOG_HOME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd HH-mm}-%i.log">
            <Filters>
                <ThresholdFilter level="fatal" onMatch="DENY" onMismatch="NEUTRAL" />
                <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>k
            <PatternLayout
                    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" />
                <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>
            <DefaultRolloverStrategy max="20" />
        </RollingRandomAccessFile>

        <RollingRandomAccessFile name="FatalFile"
                                 fileName="${LOG_HOME}/fatal.log"
                                 filePattern="${LOG_HOME}/$${date:yyyy-MM}/fatal-%d{yyyy-MM-dd HH-mm}-%i.log">
            <Filters>
                <ThresholdFilter level="fatal" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>
            <PatternLayout
                    pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" />
                <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>
            <DefaultRolloverStrategy max="20" />
        </RollingRandomAccessFile>

</Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console" />
            <AppenderRef ref="InfoFile" />
            <AppenderRef ref="ErrorFile" />
            <AppenderRef ref="FatalFile" />
        </Root>
    </Loggers>
</Configuration>

分析:

这里面的难点是在每个Appender中添加过滤器,比如,如果只想输出info级别的日志到info.log文件中,那么添加如下过滤器:

<Filters>
    <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL"/>
    <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>

这里面:ThresholdFilter中有level、onMatch、onMismatch三个键,level定义了日志的级别,onMatch和onMismatch表示匹配与不匹配的情况,其对应的值有三种:ACCEPT(放行)、DENY(拒绝)、NEUTRAL(不做任何操作)三种情况。

注意:onMatch指的是日志级别大于等于level时的操作,onMismatch表示日志级别小于level时的操作。因此,如果我们想设置日志级别为info,根据日志等级关系:

off>fatal>error>warn>info>debug>trace>all, 只需要设置大于等于warn的日志级别拒绝小于warn的日志级别放行,再加上,大于等于info的日志级别放行和小于info的日志级别拒绝,即可以得到只打印info的日志到相应的文件中。

待补充知识:异步log4j2的实现。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值