Java的日志有很多框架,框架里又有很多概念,初次接触的时候很容易让人摸不着北,这里简单整理一下。
框架
日志框架主要分为两种,一种是具体实现,一种是抽象层。
前者包括Log4j
,Logback
以及Java
自带的java.util.logging
等,都是拿来就可以直接调用的库。
后者如SLF4j
,是一个抽象层,本质上是一组利用了外观模式的API,它不提供日志的具体实现,而是将具体实现交给上一类框架,你的代码调用的是SLF4J的API而不是某一个特定的日志框架,这样做的好处是将代码和具体的日志框架解耦,你可以在不做任何代码更改的情况下更换日志框架。
举个例子,比如一开始使用的框架是Log4j
:
1 | import org.apache.log4j.Logger; |
后来要把框架换成java.util.logging
,虽然方法名一样,但是支持的参数不同,所以代码就需要改成:
1 | import java.util.logging.Logger; |
但是如果使用的是SLF4J
,代码就变成了:1
2
3
4
5
6
7
8
9
10
11import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class Scratch {
private static Logger logger = LoggerFactory.getLogger(Scratch.class.getName());
public static void main(String[] args) {
logger.info("test");
}
}
因为依赖的是SLF4J,所以无论具体的实现框架怎么换,都不用修改代码,只需引入不同的依赖和配置文件就行了。
概念
总的来说Java的日志体系里的经常涉及概念一共有三种,在不同的框架里名称可能有所区别但是做的事情都差不多。
Logger
是用来触发日志的对象,比如上面示例代码里的logger
,在需要生成日志的地方调用它,然后它会将日志传递给Appender
,Appender
负责将日志输出到指定的地方,比如控制台、文件等,在输出之前,Appender
还会用Layout
来将日志格式化成指定的格式。
Logger
Logger
在代码里实例化,获取的方式根据框架不同而有所区别,比如Log4j
是用静态类来获取:
1 | private static Logger logger = Logger.getLogger(Scratch.class); |
而SLF4j
是利用工厂类来获取:
1 | private static Logger logger = LoggerFactory.getLogger(Scratch.class.getName()); |
它们接受的参数会被用来作为logger
的标识符,一般是String
类型(Log4j提供了一个接受class
的便捷方法),如果同名的logger
已经存在则会直接返回。
最佳实践是传入当前类的类名来作为标识符。
Appender
Appender
通常在配置文件里来定义,它用来将日志输出到指定的地方,同一条日志可以被多个Appender
处理,比如同时输出到控制台和文件,输出之前会用Layout
来格式化。
Layout
Layout
通常也在配置文件里定义,可以用来指定输出的日志的格式,比如java.util.logging
中的XMLFormatter
可以将日志格式化成XML(此框架中的Layout
叫Formatter
)。
常用的Layout
还有PatternLayout
,可以自己写占位符来指定格式,部分占位符如下:
Field | Placeholder |
---|---|
message | %m |
level | %p |
exception | %e |
thread | %t |
logger | %c |
method | %m |
比如,如果指定的PatternLayout
是[%p] %t: %m
, 那么日志输出就会是:
1 | [INFO] main: initializing worker threads |
配置
Log4j
Log4j
会在项目目录下搜索一个名叫log4j.propertie
的文件并将此作为配置文件,在Log4j 1
中格式还可以是XML
,所以文件也可以是log4j.xml
。
Log4j 2
中格式可以是XML
, JSON
, 和YAML
。
示例
1 | # Root logger option |
Logback
Logback
也会在项目目录下搜索名为logback.xml
的文件来作为配置文件,它还支持Groovy,所以也可以是logback.groovy
。
示例
1 | <configuration> |
SLF4J
SLF4J
没有自己的配置,只需引入依赖并提供对应框架的配置文件就可以了,比如要把SLF4J
结合Log4j
一起用的话,可以引入如下依赖:
1 | <dependency> |
然后再提供Log4j
的配置文件就可以了。
评论(需梯子)