深入Log4J源码之Log4J Core (二)

2014-11-24 08:26:37 · 作者: · 浏览: 3
;
31 }
32 }
33 return null;
34 }

另外,在实际开发中经常会遇到要把日志信息同时写到不同地方,如同时写入文件和控制台,因而一个Logger实例中可以包含多个Appender,为了管理多个Appender,Log4J抽象出了AppenderAttachable接口,它定义了几个用于管理多个Appender实例的方法,这些方法由AppenderAttachableImpl类实现,而Logger会实例化AppenderAttachableImpl,并将这些方法代理给该实例:

1 public interface AppenderAttachable {
2 public void addAppender(Appender newAppender);
3 public Enumeration getAllAppenders();
4 public Appender getAppender(String name);
5 public boolean isAttached(Appender appender);
6 void removeAllAppenders();
7 void removeAppender(Appender appender);
8 void removeAppender(String name);
9 }

RootLogger类
在Log4J中,所有Logger实例组成一个单根的树状结构,由于Logger实例的根节点有一点特殊:它的名字为“root”,它没有父节点,它的Level字段必须设值以防止其他Logger实例都没有设置Level值的情况。基于这些考虑,Log4J通过继承Logger类实现了RootLogger类,它用于表达所有Logger实例的根节点:
1 public final class RootLogger extends Logger {
2 public RootLogger(Level level) {
3 super("root");
4 setLevel(level);
5 }
6 public final Level getChainedLevel() {
7 return level;
8 }
9 public final void setLevel(Level level) {
10 if (level == null) {
11 LogLog.error("You have tried to set a null level to root.",
12 new Throwable());
13 } else {
14 this.level = level;
15 }
16 }
17 }
NOPLogger类
有时候,为了测试等其他需求,我们希望Logger本身不做什么事情,Log4J为这种需求提供了NOPLogger类,它继承自Logger,但是基本上的方法都为空。

Level类
Level是对日志级别的抽象,目前Log4J支持的级别有FATAL、ERROR、WARN、INFO、DEBUG、TRACE,从头到尾一次级别递减,另外Log4J还支持两种特殊的级别:ALL和OFF,它们分别表示打开和关闭日志功能。

1 public static final int OFF_INT = Integer.MAX_VALUE;
2 public static final int FATAL_INT = 50000;
3 public static final int ERROR_INT = 40000;
4 public static final int WARN_INT = 30000;
5 public static final int INFO_INT = 20000;
6 public static final int DEBUG_INT = 10000;
7 public static final int TRACE_INT = 5000;
8 public static final int ALL_INT = Integer.MIN_VALUE;
9
10 public static final Level OFF = new Level(OFF_INT, "OFF", 0);
11 public static final Level FATAL = new Level(FATAL_INT, "FATAL", 0);
12 public static final Level ERROR = new Level(ERROR_INT, "ERROR", 3);
13 public static final Level WARN = new Level(WARN_INT, "WARN", 4);
14 public static final Level INFO = new Level(INFO_INT, "INFO", 6);
15 public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7);
16 public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7);
17 public static final Level ALL = new Level(ALL_INT, "ALL", 7);
每个Level实例包含了该Level代表的int值(一般是从级别低到级别高一次增大)、该Level的String表达、该Level和系统Level的对应值。

1 protected transient int level;
2 protected transient String levelStr;
3 protected transient int syslogEquivalent;
4 protected Level(int level, String levelStr, int syslogEquivalent) {
5 this.level = level;
6 this.levelStr = levelStr;
7 this.syslogEquivalent = syslogEquivalent;
8 }
Level类主要提供了判断哪个Level级别更高的方法isGreaterOrEqual()以及将int值或String值转换成Level实例的toLevel()方法:

1 public boolean isGreaterOrEqual(Level level) {
2 return this.level >= level.level;
3 }
4 public static Level toLevel(int level) {
5 return toLevel(level, DEBUG);
6 }
7 public static Level toLevel(int level, Level defaultLevel) {
8 switch(level) {
9 case OFF_INT: return OFF;
10 case FATAL_INT: return FATAL;
11 case ERROR_INT: return ERROR;
12 case WARN_INT: return