1、添加配置
Maven项目中pom.xml中添加:
<!-- 日志文件 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
举个简单的例子:
在项目中建立一个测试类,将下面简单的代码输入进去
package com.qcby.Test;//自己修改自己的包名
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Logger;
public class TestLog4j2 {//自己修改自己的class名
public static void main(String[] args) {
Logger log = (Logger) LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
log.trace("trace level");
log.debug("debug level");
log.info("info level");
log.error("error level");
log.fatal("fatal level");
}
}
执行上述代码,输出如下提示:
ERROR StatusLogger 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.
11:09:20.881 [main] ERROR - error level
11:09:20.886 [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>
<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>