
Log4j对Java开发者来说是经常使用到的日志框架,我每次使用都对它的配置文件头大,网上搜一个别人的例子自己改巴改巴,草草了事。再次使用时,又忘了怎么回事了。这次突然来了兴趣,想看看它具体是怎么做的,做个笔记,加深一下印象。
目前的版本是 log4j:log4j:1.2.17
Log4j的输出类都需要实现的接口,为了用户自定义log输出策略,抽象出了以下几点功能
过滤链
log输出
错误处理
log格式
这个接口只定义了一个方法 void activateOptions();,用于按需初始化一些配置。
既然是Skeleton,那它必须是最核心的骨架。这个类主要做了以下几个事
过滤链(链表)增删操作
protected Filter headFilter;
protected Filter tailFilter;
public void addFilter(Filter newFilter) {
if(headFilter == null) {
headFilter = tailFilter = newFilter;
} else {
tailFilter.setNext(newFilter);
tailFilter = newFilter;
}
}
public void clearFilters() {
headFilter = tailFilter = null;
}
定义了日志优先级 threshold “门槛”,实现日志的分级输出
protected Priority threshold;//默认为空
public boolean isAsSevereAsThreshold(Priority priority) {
return ((threshold == null) || priority.isGreaterOrEqual(threshold));
}
log的输出核心逻辑
public synchronized void doAppend(LoggingEvent event) {
if(closed) {
LogLog.error("Attempted to append to closed appender named ["+name+"].");
return;
}
//日志级别拦截
if(!isAsSevereAsThreshold(event.getLevel())) {
return;
}
Filter f = this.headFilter;
//结合Filter实现类自身的优先级[停止输出、立即输出、依次过滤后输出]进行过滤,
FILTER_LOOP:
while(f != null) {
switch(f.decide(event)) {
case Filter.DENY: return;
case Filter.ACCEPT: break FILTER_LOOP;
case Filter.NEUTRAL: f = f.getNext();
}
}
//具体的输出开放给子类实现
this.append(event);
}
下放的权限
//子类只需要关心日志具体的输出方式
abstract protected void append(LoggingEvent event);
//配置方法,子类可以按自己的需求覆写
public void activateOptions() {}
继承AppenderSkeleton,用户可选择将log按字符流或字节流输出。增加了以下特性
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-32111-1.html
给观众带来更多更好的作品
或者让男的变太监