是否可以扩展一下logback,来实现自己的logger api,使得打印更加容易,一些关键信息是内置打印的呢?
logback的三大模块(logback-core, logback-classic and logback-access):
- logback-core:是最基础的模块,提供了logback的基础架构实现
- logback-classic:提供了core的扩展,实现了slf4j的接口。增加了log4j的功能
- logback-access:一个集成servlet容器提供http 请求日志的记录功能的模块。
我们平时用到的主要是logback-classic模块里面的功能
关于Appender
对于logback来说,一个日志输出的目的地被称作为appender。一个logger可以有多个appender。
如果顶层的logger,如rootLogger配置了一个console的appender,当下面一个子logger,比如org.apache配置的是一个file的appender。那么这个org.apache的logger,同时会具有从rootLogger继承过来的console appender,以及其单独设置的file appender,可以通过设置additivity flag 为false(默认是true) 来屏蔽父辈的appender继承。一图剩千言:
The table below shows an example:
打印日志时的代码逻辑
我们来分析一下,当调用一个logger的info方法之后,logback是怎么执行的,先看一下时序图:
1、Get the filter chain decision (这个没想到翻译成什么):
TurboFilter 可以设置一些上下文变量,或者过滤一些日志信息,比如Marker, Level, Logger, message, or the Throwable等。TurboFilter 会返回一下三种判断结果:
- FilterReply.DENY:整个日志打印请求就会丢弃,终止打印
- FilterReply.NEUTRAL:跳到第二步执行,进一步判断是否要打印日志
- FilterReply.ACCEPT:跳到第三步,构造打印日志对象
2、Apply the basic selection rule
更加基础的规则对日志进行过滤,比如如果设置了warn基本的日志,那么info日志是不会被输出的。
3、Create a LoggingEvent object
在这一步中,会使用日志打印所需要的所有相关的信息,以及MDC信息来创建一个LoggingEvent对象。LoggingEvent对象的所有field都是延迟加载的,当需要用到的时候才会被初始化(这个是怎么做的呢?)
4、Invoking appenders
5、 Formatting the output
6、Sending out the LoggingEvent