Log4j输出日志 | Log4j write log
Log4j输出日志分为六个步骤:全局开关控制、日志等级过滤、封装日志信息、过滤器处理、日志信息格式化、输出至文件。下面分两个环节来介绍这六个步骤是如何实现的:
1、第一环节:预处理。
当调用Log4j的方法(如:debug(String, Throwable)、info(String, Throwable))输出日志时,首先对日志信息进行预处理,其序列图如下;
说明:
- isDisabled(int level):根据全局日志等级threshold进行判断,如果日志等级低于threshold,不输出日志。
- isGreaterOrEquals(Priority r):根据当前logger配置的日志等级level进行判断,如果日志等级低于当前logger配置的日志等级,不输出日志。
- foredLog(String fqcn Priority level, Object message, Throwable t):将日志信息封装成LoggingEvent对象。
- callAppenders(LoggingEvent event):将LoggingEvent对象分发给所有的Appender。其实现代码如下:
public void callAppenders(LoggingEvent event) {
int writes = 0;
for (Category c = this; c != null; c = c.parent) {
// Protected against simultaneous call to addAppender,
// removeAppender,...
synchronized (c) {
if (c.aai != null) {
writes += c.aai.appendLoopOnAppenders(event);
}
if (!c.additive) {
break;
}
}
}
if (writes == 0) {
repository.emitNoAppenderWarning(this);
}
}
public int appendLoopOnAppenders(LoggingEvent event) {
int size = 0;
Appender appender;
if (appenderList != null) {
size = appenderList.size();
for (int i = 0; i < size; i++) {
appender = (Appender) appenderList.elementAt(i);
appender.doAppend(event);
}
}
return size;
}
2、第二环节:输出日志。
输出日志前还有两道工序需要处理:Filter处理和日志信息格式化。其执行序列图如下:
相应的代码如下:
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_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);
}
protected void subAppend(LoggingEvent event) {
this.qw.write(this.layout.format(event));
if (layout.ignoresThrowable()) {
String[] s = event.getThrowableStrRep();
if (s != null) {
int len = s.length;
for (int i = 0; i < len; i++) {
this.qw.write(s[i]);
this.qw.write(Layout.LINE_SEP);
}
}
}
if (shouldFlush(event)) {
this.qw.flush();
}
}
说明:
- decide(LoggingEvent event):有三种返回值 DENY、ACCEPT、NEUTRAL,DENY表示丢弃当前日志信息,ACCEPT表示输出当前日志信息,NEUTRAL表示继续下一个Filter。Filter只能在XML配置文件中使用,Properties文件中不支持。
- format(LoggingEvent event):对日志进行格式化处理。
- write(String string):将日志信息输出至目的地(文件、数据库或网格)。