今天晚上本来想来写一下Logger怎么记录日志,以及Appender组件。不过9点才从丈母娘家回来,又被几个兄弟喊去喝酒,结果回来晚了,所以时间就只够写一篇Logger类的源码分析了。Appender找时间再写
上篇博客介绍了LoggerContext怎么生成Logger,Logger是logback的核心类,也是所有日志框架的核心类。这篇博客详细介绍一下Logger的各字段和方法,重点介绍Logger类是怎样记录日志的
老规矩,首先看图:
Logger类实现了slf4j框架定义的Logger接口,然后这个类和LoggerContext是互相引用的(因为Logger需要依赖LoggerContext的TurboFilter等组件)。并且Logger实现了AppenderAttachable接口,它实现该接口的方式,是持有AppenderAttachableImpl类,然后委托该类来实现AppenderAttachable接口定义的方法,这里用到了代理模式,是一个比较精巧的设计
看到了Logger类的全景图,接下来我们逐一介绍Logger类中的各个字段,最后重点介绍Logger类是怎样记录日志的
首先看看Logger的字段
上篇博客介绍了LoggerContext怎么生成Logger,Logger是logback的核心类,也是所有日志框架的核心类。这篇博客详细介绍一下Logger的各字段和方法,重点介绍Logger类是怎样记录日志的
老规矩,首先看图:
Logger类实现了slf4j框架定义的Logger接口,然后这个类和LoggerContext是互相引用的(因为Logger需要依赖LoggerContext的TurboFilter等组件)。并且Logger实现了AppenderAttachable接口,它实现该接口的方式,是持有AppenderAttachableImpl类,然后委托该类来实现AppenderAttachable接口定义的方法,这里用到了代理模式,是一个比较精巧的设计
看到了Logger类的全景图,接下来我们逐一介绍Logger类中的各个字段,最后重点介绍Logger类是怎样记录日志的
首先看看Logger的字段
static int instanceCount = 0;
/**
* The name of this logger
*/
private String name;
// The assigned levelInt of this logger. Can be null.
private Level level;
// The effective levelInt is the assigned levelInt and if null, a levelInt is
// inherited form a parent.
private int effectiveLevelInt;
/**
* The parent of this category. All categories have at least one ancestor
* which is the root category.
*/
private Logger parent;
/**
* The children of this logger. A logger may have zero or more children.
*/
private List<Logger> childrenList;
/**
* It is assumed that once the 'aai' variable is set to a non-null value, it
* will never be reset to null. it is further assumed that only place where
* the 'aai'ariable is set is within the addAppender method. This method is
* synchronized on 'this' (Logger) protecting against simultaneous
* re-configuration of this logger (a very unlikely scenario).
*
* <p>
* It is further assumed that the AppenderAttachableImpl is responsible for
* its internal synchronization and thread safety. Thus, we can get away with
* *not* synchronizing on the 'aai' (check null/ read) because
* <p>
* 1) the 'aai' variable is immutable once set to non-null
* <p>
* 2) 'aai' is getAndSet only within addAppender which is synchronized
* <p>
* 3) all the other methods check whether 'aai' is null
* <p>
* 4) AppenderAttachableImpl is thread safe
*/
private transient AppenderAttachableImp