0%

log4j

log4j是一个jar包,接口和实现都是在一起的,log4j2的接口和实现是分开的,这是log4j2的运行时依赖的地址,和slf4j的使用形式差不多

日志api/框架 桥接jar包(也可以称为适配器 被桥接对象 描述
log4j-api log4j-core 直接实现,不用桥接
log4j-1.2-api log4j-api/log4j-core log4j的jar中api的覆写,将项目中对log4j的调用转移到log4j2,(需要删除原有log4j的jar包)
commons-logging log4j-jcl log4j-api/log4j-core commons-logging 使用log4j2作为实现
slf4j-api log4j-slf4j-impl log4j-api/log4j-core 桥接包可以理解为log4j2作为slf4j的实现
Java Util Logging log4j-jul log4j-api/log4j-core
log4j-api log4j-to-slf4j slf4j-api及其实现 可以通过此链接到logback(logback-classic/logback-core)

log4j2

1
2
3
4
5
6
<log4j.version>2.17.2</log4j.version>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
1
mvn clean dependency:tree 
1
2
3
4
[INFO] +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.17.2:compile
[INFO] | +- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] | +- org.apache.logging.log4j:log4j-api:jar:2.17.2:compile
[INFO] | \- org.apache.logging.log4j:log4j-core:jar:2.17.2:runtime

Log4j patternLayout

如果您希望基于某种模式生成特定格式的日志信息,可使用 org.apache.Log4j.PatternLayout 格式化您的日志信息。

PatternLayout 继承自抽象类 org.apache.Log4j.Layout,覆盖了其 format() 方法,通过提供的模式,来格式化日志信息。

PatternLayout 是一个简单的 Layout 对象,提供了如下属性,该属性可通过配置文件

conversionPattern
设置转换模式,默认为 %r [%t] %p %c %x - %m%n

模式转换字符

下面的表格解释了上面模式中用到的字符,以及所有定制模式时能用到的字符:

转换字符 含义
c category的名称,可使用{n}限制输出的精度。例如:logger名为”a.b.c”,%c{2}将输出”b.c”。
C 产生log事件的java完全限定类名。可使用{n}限制输出的精度。例如:“org.apache.xyz.SomeClass”,%C{2}将输出“SomeClass”。
d 时间和日期的输出格式,例如:%d{yyyy MM dd HH:mm:ss,SS},可不带后面的日期格式字符。
F 产生log事件的java源文件名,带“.java”后缀及包名称。
l log发生位置的详细描述,包括方法名、文件名及行号。
L log发生在源文件中的位置。
m log事件的消息内容。
M log发生时所在的方法名称。
n 根据所运行的平台输出相应的行分隔字符。
p log事件的级别。
r 自程序运行至log事件产生所经过的时间。
t 产生log的线程名称。
x 用于与产生该日志事件的线程相关联输出的NDC(嵌套诊断上下文)
X 在X转换字符后面是键为的MDC。例如  X{clientIP} 将打印存储在MDC对键clientIP的信息
% 文字百分号 %%将打印%标志

格式修饰符

缺省情况下,信息保持原样输出。但是借助格式修饰符的帮助,就可调整最小列宽、最大列宽以及对齐。

PatternLayout 示例

下面是为 PatternLayout 编写的一个简单配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Define the root logger with appender file
log=log
log4j.rootLogger=DEBUG, FILE, stdout
# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out
# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{yyyy-MM-dd}-%t-%x-%-5p-%-10c:%m%n
# Define the file appender
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} %l %m%n

下面是生成日志信息的 Java 程序:

1
2
3
LOG.info("checkpointId: {}", savepoint.getCheckpointId());
LOG.info("version: {}", savepoint.getVersion());
LOG.info("version: {}", savepoint.getMasterStates());

编译并运行上述程序,会在目录 log 下生成一个名为 log.out 的文件,该文件包含如下日志信息:

1
2
3
[INFO ] 2021-10-12 14:12:48,232 com.tencent.flake.training.savepoint.Main.main(Main.java:23) checkpointId: 398
[INFO ] 2021-10-12 14:12:48,237 com.tencent.flake.training.savepoint.Main.main(Main.java:24) version: 2
[INFO ] 2021-10-12 14:12:48,237 com.tencent.flake.training.savepoint.Main.main(Main.java:25) version: []

更多格式样例

1
%d{yyyy-MM-dd HH\:mm\:ss,SSS} %-5p [%t] %-60c %x\:%L - %m%n
1
2
3
2021-10-12 14:19:35,851 INFO  [main] com.tencent.flake.training.savepoint.Main                    :23 - checkpointId: 398
2021-10-12 14:19:35,855 INFO [main] com.tencent.flake.training.savepoint.Main :24 - version: 2
2021-10-12 14:19:35,855 INFO [main] com.tencent.flake.training.savepoint.Main :25 - version: []

问题

StaticLoggerBinder

1
2
3
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

org.slf4j.impl.StaticLoggerBinder 是在适配器里面实现的,需要增加slf4j-log4j12、log4j-slf4j-impl、slf4j-jdk4

No appenders

1
2
3
log4j:WARN No appenders could be found for logger (com.tencent.flake.training.savepoint.Main).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

没有找到appender,需要配置properties或指定使用默认configurator.

1
BasicConfigurator.configure();

log4j 是目前最常见的日志系统之一,本文主要总结log4j的使用和配置.

log4j的组件

  • logger
  • appender
  • level
  • layout

logger-记录器 打印事件

logger 可以理解为日志记录器,它有name、appender和level等属性.
当调用

1
Logger logger = LoggerFactory.getLogger(AClass.class);

时,logger变量即为名称为AClass类的全名的logger.

如果使用

1
Logger logger = LoggerFactory.getLogger("myRedo");

logger变量即为名称为myRedo的logger

  1. 所有的logger的根都是rootLogger

  2. 一般情况下,取类名作为logger的名称. 父子关系遵从Java package的方法

  3. 子logger默认继承父logger的所有的配置. 子logger的配置会覆盖父logger的配置

  4. logger的名称可以为任意字符串

  5. log4j可以使用多种配置方式: properties文件、xml文件和Java代码

  6. 使用Java代码配置时,可以指定为基本配置: BasicConfigurator.configure();

  7. 可以指定特定包的log
    样例: 使用代码的方式配置特定包的logger

    1
    2
     Logger.getRootLogger().setLevel(Level.WARN);
    Logger.getLogger("cd.itcast.core").setLevel(Level.DEBUG);

appender 打印目的地

log4j定义了多种appender:

1
2
3
4
5
6
- org.apache.log4j.ConsoleAppender(控制台)
- org.apache.log4j.FileAppender(文件)
- org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
- org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
- org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
- org.apache.log4j.jdbc.JDBCAppender(将日志信息写入数据库)

在properties文件中配置

1
log4j.appender.<appenderName> = fully.qualified.name.of.appender.class

Appender类的属性

ConsoleAppender

Threshold=DEBUG :指定日志消息的输出最低层次.
ImmediateFlush=true :默认值是true,意谓着所有的消息都会被立即输出.
Target=System.err :默认情况下是:System.out,指定输出控制台

FileAppender

Threshold=DEBUF :指定日志消息的输出最低层次.
ImmediateFlush=true :默认值是true,意谓着所有的消息都会被立即输出.
File=mylog.txt :指定消息输出到mylog.txt文件.
Append=false :默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容.

RollingFileAppender

Threshold=DEBUG :指定日志消息的输出最低层次.
ImmediateFlush=true :默认值是true,意谓着所有的消息都会被立即输出.
File=mylog.txt :指定消息输出到mylog.txt文件.
Append=false :默认值是true,即将消息增加到指定文件中,false指将消息覆盖指定的文件内容.
MaxFileSize=100KB : 后缀可以是KB, MB 或者是 GB. 在日志文件到达该大小时,将会自动滚动,即将原来的内容移到mylog.log.1文件.
MaxBackupIndex=2 :指定可以产生的滚动文件的最大数.
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n

DailyRollingFileAppender

DatePattern
layout
Encoding
MaxBackupIndex

level 输出级别

ERROR、WARN、INFO、DEBUG

  • ERROR 为严重错误 主要是程序的错误
  • WARN 为一般警告,比如session丢失
  • INFO 为一般要显示的信息,比如登录登出
  • DEBUG 为程序的调试信息

layout

-X号: X信息输出时左对齐;

1
2
3
4
5
6
7
8
9
10
11
12
%p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
%d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%r: 输出自应用启动到输出该log信息耗费的毫秒数
%c: 输出日志信息所属的类目,通常就是所在类的全名
%t: 输出产生该日志事件的线程名
%l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数. 举例:Testlog4.main (TestLog4.java:10)
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中.
%%: 输出一个"%"字符
%F: 输出日志消息产生时所在的文件名称
%L: 输出代码中的行号
%m: 输出代码中指定的消息,产生的日志具体信息
%n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行

日志信息格式中几个符号所代表的含义:
可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式. 如:

  1. %20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐.
  2. %-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,”-“号指定左对齐.
  3. %.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格.
  4. %20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边较远输出的字符截掉.

log4j性能优化

  1. 为了避免多次打开文件引起资源的浪费,log4j当打开文件或连接数据库后,会始终保持着连接,直到引用关闭.
    因此, 当引用运行过程中,删除文件. log4j不会再次创建该文件.
  2. logger文件是懒生成模式:当打印时,判断是否需要创建新文件

通过命令行执行log4j配置文件

1
2
3
java -jar -Dlog4j.configurationFile=file:/data/work/oceanus2/conf/log4j2-spring.properties \
-Dlogging.config=/data/work/oceanus2/conf/log4j2-spring.properties \
my_application.jar

典型应用

配置非类名logger及代码获取logger的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
###################
# rootLogger的级别为INFO,appender为terminal01和allToFile
###################
log4j.rootLogger=INFO,terminal01,allToFile
###################
# Console Appender
###################
log4j.appender.terminal01=org.apache.log4j.ConsoleAppender
log4j.appender.terminal01.Target=System.out
log4j.appender.terminal01.layout=org.apache.log4j.PatternLayout
log4j.appender.terminal01.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.sss},%c,%-p,%m %n
########################
# Rolling File
########################
log4j.appender.allToFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.allToFile.File=/data/logs/blog-all.log
log4j.appender.allToFile.Append=true
log4j.appender.allToFile.MaxFileSize=100MB
log4j.appender.allToFile.MaxBackupIndex=7
log4j.appender.allToFile.Encoding=UTF-8
log4j.appender.allToFile.layout=org.apache.log4j.PatternLayout
log4j.appender.allToFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.sss},%c,%-p,%m %n
########################
# 指定某个包的logger
########################
log4j.logger.com.abc.engin=INFO,engin
########################
# appender engin
########################
log4j.additivity.engin=false
## 是否追加到root appender中
log4j.appender.engin=org.apache.log4j.DailyRollingFileAppender
log4j.appender.engin.File=/data/logs/engin.log
log4j.appender.engin.Append=true
log4j.appender.engin.MaxFileSize=500MB
log4j.appender.engin.MaxBackupIndex=7
log4j.appender.engin.Encoding=UTF-8
log4j.appender.engin.layout=org.apache.log4j.PatternLayout
log4j.appender.engin.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.sss},%c,%-p,%m %n
########################
# 非类名logger
########################
log4j.logger.error=ERROR,errorAppender
########################
# appender errorAppender
########################
log4j.appender.errorAppender=org.apache.log4j.DailyRollingFileAppender
log4j.appender.errorAppender.File=/data/logs/blog-error.log
log4j.appender.errorAppender.Append=true
log4j.appender.errorAppender.MaxFileSize=500MB
log4j.appender.errorAppender.MaxBackupIndex=7
log4j.appender.errorAppender.Encoding=UTF-8
log4j.appender.errorAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.errorAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.sss},%c,%-p,%m %n

打印

1
2
3
4
5
Logger logger = LoggerFactory.getLogger(AClass.class);
logger.error("this is an error log");
// 获取名称为error的logger
Logger loggerError = LoggerFactory.getLogger("error");
loggerError.error("this is an error log");

从Java代码获取logger的配置信息

1
2
3
4
5
org.apache.log4j.Logger loggerError = org.apache.log4j.Logger.getLogger("error");
Appender appender = loggerError.getAppender("errorAppender");
DailyRollingFileAppender errorAppender = (DailyRollingFileAppender) appender;
String fileName = errorAppender.getFile();
String datePattern = errorAppender.getDatePattern();

每个小时打印一个文件

配置文件的方式

1
2
3
4
5
6
7
8
9
10
11
log4j.logger.redo=ERROR,redoLogger
# appender for redo logger
log4j.appender.redoLogger=org.apache.log4j.DailyRollingFileAppender
log4j.appender.redoLogger.File=/data/logs/my-redo.log
log4j.appender.redoLogger.Append=true
log4j.appender.redoLogger.MaxFileSize=500MB
log4j.appender.redoLogger.MaxBackupIndex=7
log4j.appender.redoLogger.Encoding=UTF-8
log4j.appender.redoLogger.layout=org.apache.log4j.PatternLayout
log4j.appender.redoLogger.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.sss},%c,%-p,%m \n
log4j.appender.redoLogger.DatePattern='.'yyyy-MM-dd-HH

Java代码的方式

1
2
3
4
5
DailyRollingFileAppender redoAppender = new DailyRollingFileAppender();
redoAppender.setDatePattern("'.'yyyy-MM-dd-HH");

Logger loggerRedo = Logger.getLogger("redo");
loggerRedo.addAppender(appender);

使用

1
2
3
public static final Logger redoLogger = LoggerFactory.getLogger("redo");
...
redoLogger.error("something is wrong");

下面的列表
The following list shows all the date patterns which have defined by log4j,

name DatePattern sample
Minutely '.'yyyy-MM-dd-HH-mm application.log.2013-02-28-13-54
Hourly '.'yyyy-MM-dd-HH application.log.2013-02-28-13
Half-daily '.'yyyy-MM-dd-a application.log.2013-02-28-AM app.log.2013-02-28-PM
Daily '.'yyyy-MM-dd application.log.2013-02-28
Weekly '.'yyyy-ww application.log.2013-07 app.log.2013-08
Monthly '.'yyyy-MM application.log.2013-01 app.log.2013-02

自定义 writerAppender

log4j将日志输出到swing控件

自定义 writer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class LogWriter extends Writer {

private LogListModel model;

public LogWriter(LogListModel model) {
this.model = model;
}

@Override
public void write(int c) throws IOException {
model.addElement("" + c);
}

@Override
public void write(char[] cbuf) throws IOException {
model.addElement(new String(cbuf));
}

@Override
public void write(String str) throws IOException {
model.addElement(str);
}

@Override
public void write(String str, int off, int len) throws IOException {
model.addElement(str);
}

@Override
public void write(char[] cbuf, int off, int len) throws IOException {
model.addElement(new String(cbuf));
}

@Override
public void flush() throws IOException {
}

@Override
public void close() throws IOException {
}
}

创建logger与Swing组件

1
2
3
4
5
6
7
8
9
10
11
private Logger loggerA = LoggerFactory.getLogger("A1");
private LogListModel logListModel;

logListModel = new LogListModel();
JList ml = new JList(logListModel);

WriterAppender writeappender = new WriterAppender(new SimpleLayout(), new LogWriter(logListModel));
writeappender.setName("A1");
writeappender.setImmediateFlush(true);
Logger.getRootLogger().addAppender(writeappender);
Logger.getRootLogger().setLevel(Level.INFO);

应用

1
2
3
4
5
6
log4j.rootLogger=DEBUG,STDOUT

log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
log4j.appender.STDOUT.Target=System.out
log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
log4j.appender.STDOUT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.sss},%c,%-p,%m %n

log4j 1升级到log4j 2

删除项目中引用的 log4j jar 包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>

引入 log4j2  jar 包


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.0</version>
</dependency>

若使用了 slf4j 需要引入 

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

删除 log4j.properties  新建 log4j2.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?xml version="1.0" encoding="UTF-8" ?>
<configuration monitorInterval="5">

<appenders>
<!-- 将日志输出到控制台-->
<console >
<!-- 日志输出格式-->
<PatternLayout pattern="%d{yyyy-MM-dd hh:mm:ss}:%p %t %c %l- %mn"/>
<!-- 控制台只输出level及其以上的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
</console>

<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
<File >
<PatternLayout pattern="../logs/mapi/test/test.log.%d{yyyyMMdd}.log"/>
</File>
示例1:
<RollingFile
filePattern="../logs/mapi/consumer/consumer.log.%d{yyyyMMdd}.log">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss:SSS} %p %t %c{1} - %mn</Pattern>
</PatternLayout>
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<!--interval属性用来指定多久滚动一次,默认是1 hour filePattern最后时间单位为天则为一天-->
<TimeBasedTriggeringPolicy modulate="true" inyrtval="1"/>
</Policies>
</RollingFile>

示例2:
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile
filePattern="../logs/mapi/consumer/consumer.log.%d{yyyyMMdd}_%i.log.gz">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss:SSS} %p %t %c{1} - %mn</Pattern>
</PatternLayout>
<Policies>
<!--interval属性用来指定多久滚动一次,默认是1 hour-->
<TimeBasedTriggeringPolicy interval="1"/>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件开始覆盖-->
<!-- 1.max参数是与filePattern中的计数器%i配合起作用的,若filePattern为filePattern="../logs/mapi/consumer/consumer.log.%d{yyyyMMdd}.log">,由于没有设置%i计数器,max参数将不起作用。-->

<!-- 2.max参数不是需要保留的文件的最大个数,日志文件date/time pattern不再符合filePattern时,计算器将被重置为1,日志总个数超过了max的指定值。-->

<!-- 可认为max参数规定了一定时间范围内归档文件的最大个数,默认为7-->
<DefaultRolloverStrategy max="15"/>
</RollingFile>
</appenders>
</configuration>

log4j2 配置参数详解

日志级别:如果一条日志信息的级别大于等于配置文件的级别,就记录。

  • trace:追踪,就是程序推进一下,可以写个 trace 输出
  • debug:调试,一般作为最低级别,trace 基本不用。
  • info:输出重要的信息,使用较多
  • warn:警告,有些信息不是错误信息,但也要给程序员一些提示。
  • error:错误信息。用的也很多。
  • fatal:致命错误。

PatternLayout 自定义日志布局:

1
2
3
4
5
6
7
8
9
10
11
12
13
%d{yyyy-MM-dd HH:mm:ss, SSS} : 日志生产时间,输出到毫秒的时间
%-5level : 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
%c : logger的名称(%logger)
%t : 输出当前线程名称
%p : 日志输出格式
%m : 日志内容,即 logger.info("message")
%n : 换行符
%C : Java类名(%F)
%L : 行号
%M : 方法名
%l : 输出语句所在的行数, 包括类名、方法名、文件名、行数
hostName : 本地机器名
hostAddress : 本地ip地址

log4j2 配置详解

根节点 Configuration
有两个属性:

  • status
  • monitorinterval

有两个子节点:

  • Appenders
  • Loggers(表明可以定义多个 Appender 和 Logger).

status 用来指定 log4j 本身的打印日志的级别.
monitorinterval 用于指定 log4j 自动重新配置的监测间隔时间,单位是 s, 最小是 5s.

Appenders 节点
常见的有三种子节点: Console、RollingFile、File

Console 节点用来定义输出到控制台的 Appender.

  • name: 指定 Appender 的名字.
  • target:SYSTEM_OUT 或 SYSTEM_ERR, 一般只设置默认: SYSTEM_OUT.
  • PatternLayout: 输出格式,不设置默认为:%m%n.

File 节点用来定义输出到指定位置的文件的 Appender.

  • name: 指定 Appender 的名字.
  • fileName: 指定输出日志的目的文件带全路径的文件名.
  • PatternLayout: 输出格式,不设置默认为:%m%n.

RollingFile 节点用来定义超过指定条件自动删除旧的创建新的 Appender.

  • name: 指定 Appender 的名字.
  • fileName: 指定输出日志的目的文件带全路径的文件名.
  • PatternLayout: 输出格式,不设置默认为:%m%n.
  • filePattern : 指定当发生 Rolling 时,文件的转移和重命名规则.
  • Policies: 指定滚动日志的策略,就是什么时候进行新建日志文件输出日志.
  • TimeBasedTriggeringPolicy:Policies 子节点,基于时间的滚动策略,interval 属性用来指定多久滚动一次,默认是 1 hour。modulate=true 用来调整时间:比如现在是早上 3am,interval 是 4,那么第一次滚动是在 4am,接着是 8am,12am… 而不是 7am.
  • SizeBasedTriggeringPolicy:Policies 子节点,基于指定文件大小的滚动策略,size 属性用来定义每个日志文件的大小.
  • DefaultRolloverStrategy: 用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的,创建新的 (通过 max 属性)。

Loggers 节点,常见的有两种: Root 和 Logger.
Root 节点用来指定项目的根日志,如果没有单独指定 Logger,那么就会默认使用该 Root 日志输出

  • level: 日志输出级别,共有 8 个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < AppenderRef:Root 的子节点,用来指定该日志输出到哪个 Appender.
  • Logger 节点用来单独指定日志的形式,比如要为指定包下的 class 指定不同的日志级别等。
  • level: 日志输出级别,共有 8 个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
  • name: 用来指定该 Logger 所适用的类或者类所在的包全路径, 继承自 Root 节点.
  • AppenderRef:Logger 的子节点,用来指定该日志输出到哪个 Appender, 如果没有指定,就会默认继承自 Root. 如果指定了,那么会在指定的这个 Appender 和 Root 的 Appender 中都会输出,此时我们可以设置 Logger 的 additivity=”false” 只在自定义的 Appender 中进行输出。
  1. How to rotate log files based on time rather than size in Log4j?

  2. Log4j详细介绍(五)—-输出地Appender

  3. log4j2的入门到了解