0%

log4j和slf4j配置

前言

之前自己写的时候哪管什么log不log的,遇到啥都是直接sout。
后来在写自己的框架的时候,发现不行啊,我要做一个log出来,像spring启动那样。
来了美团,这里的log更加的严谨了,除了要运行的时候打印出log,还要把log分类分时间打到本地的文件里,

当然这还不够,美团有个cat框架,还需要我们把log通过网络,打到专门管理log的服务器上去。

大的系统log是很有必要的,这样出了问了log能给我们很大的启示。

Log框架

Java的Log框架是比较乱的,之前一直没搞懂,不知道依赖关系。

主要的有

  • apachelog4j
  • 升级版的log4j2
  • apachecommon logging
  • java.util.Logging
  • slf4j
  • LogBack

不自己去了解一下其实是很乱的,光apache的log就有好几套。

不过主流的还是log4jLogBack,但是为了避免框架的Log和用户的Log不一样。
总不能一个系统里就有几套不同的Log吧。
于是slf4j出现了,这个框架,不提供实现,只提供接口。
幸运的是Log4jLogBack都实现了这个框架的接口。
所以现在大多数还是直接调用slf4j的接口。实现的话,我们选一个去import一下就行。

依赖

1
2
3
4
5
6
7
8
9
10
11
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.10.0</version>
</dependency>

log4j为例,首先我们得引入slf4j的规定的接口包,然后再引入log4j的实现包就行了。

再加上log的配置文件。(见下)

在代码中就直接写

1
2
3
4
5
6
public class Main {
private static final Logger log = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
log.info("dddddddd");
}
}

就可以了。

配置文件

log4j的配置文件其实也不难。
resources目录下建立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
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>

<Properties>
<Property name="log-path">/Users/zhuyichen/log/testLogs.txt</Property>
</Properties>

<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="file" fileName="${log-path}" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
<RollingFile name="rollingFile" fileName="${log-path}"
filePattern="${sys:user.home}/log/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"
append="true">
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100MB"/>
</Policies>
<DefaultRolloverStrategy max="20"/>
</RollingFile>
</Appenders>

<Loggers>

<Logger name="Main" level="error, info" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Root level="all">
<AppenderRef ref="Console"/>
<AppenderRef ref="file"/>
</Root>
</Loggers>
</Configuration>

Properties

首先Properties的条目是随便写的,只是方便我们下面引用的时候方便管理而已。
比如我们把我的log目录文件路径放进去了。
下面就可以用${log-path}来引用

Appenders

下面就是Appenders,这里相当于我们设定几个log模式。

Consoleconsole直接打印的模式。
PatternLayout是打印出来的样式。

File就是打印到文件的模式。

  • name 名字,由下面的Logger引用用
  • fileName Log文件的路径
  • append 每次启动,log是加到文件里,还是清空文件。

RollingFile就是轮转的Log,可以指定策略创建新的,删除旧的。
叫滚动日志

  • name Appenders的名字
  • fileName文件的名字
  • filePattern就是指定创建新的log文件的格式
  • Policies 指定滚动日志的策略
    • TimeBasedTriggeringPolicy 基于时间的滚动策略
    • SizeBasedTriggeringPolicy 基于指定文件大小的滚动策略,size属性用来定义每个日志文件的大小
    • DefaultRolloverStrategy 用来指定同一个文件夹下最多有几个日志文件时开始删除最旧的

Loggers

Loggers才是真正控制我们Log的地方。

一般有两种节点,一个是Logger,一个是Root

level:日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF

按这个级别排序呢,就是说如果是all,那么大于等于它的级别的都会输出。

Logger一般单独指认某个类或者某个的输出日志。

  • name 指某个类所在全程或者某个包的全程
  • level 输出的日记级别
  • additivity 如果设为false,那么就不会在下面的Root节点再输出了。

Root是个特殊的条目,就是剩下来的所有
相比较Logger配置只有一个level

在每个配置中具体日志打到哪儿,需要引用我们上面定义的Appender了。
你需要这个Log打印到哪儿,就在里面增加一个AppenderRef条目。

比如我的Root节点需要全部既打印到终端,又打印到文件,我就把两个都引用进去。

参考

https://www.cnblogs.com/hafiz/p/6170702.html
官方文档