log4j源码学习---log打印
2012-08-31 16:47 Polarisary 阅读(492) 评论(1) 编辑 收藏 举报接上篇,继续学习log4j源码---log4j打印日志流程
log4j最核心的6个类:
Logger:对日志行为的抽象,封装了不同级别的日志记录接口
Level:对日志级别的抽象
Appender:对日志记录形式的抽象
Layout:对格式的抽象
LoggingEvent:对一次日志记录过程中日志信息的抽象
LoggerRepository:Logger实例的容器
1.首先判断该级别的日志是否可以打印,不能的话直接退出,通过getEffectiveLevel()方法遍历其父Logger直到找到一个有效的Level,并与本日志(logger.info()就是INFO)级别比较小于则调用forcedLog()打印日志
1 /** 2 3 This is the most generic printing method. It is intended to be 4 invoked by <b>wrapper</b> classes. 5 6 @param callerFQCN The wrapper class' fully qualified class name. 7 @param level The level of the logging request. 8 @param message The message of the logging request. 9 @param t The throwable of the logging request, may be null. */ 10 public 11 void log(String callerFQCN, Priority level, Object message, Throwable t) { 12 if(repository.isDisabled(level.level)) { 13 return; 14 } 15 if(level.isGreaterOrEqual(this.getEffectiveLevel())) { 16 forcedLog(callerFQCN, level, message, t); 17 } 18 }
2.把日志信息封装成LoggingEvent,并调用callAppenders()委托AppenderAttachableImpl实例遍历所有Appender并调用doAppend()方法,doAppend()会过滤掉一下配置的过滤,再调用append()方法。
1 /** 2 Call the appenders in the hierrachy starting at 3 <code>this</code>. If no appenders could be found, emit a 4 warning. 5 6 <p>This method calls all the appenders inherited from the 7 hierarchy circumventing any evaluation of whether to log or not 8 to log the particular log request. 9 10 @param event the event to log. */ 11 public 12 void callAppenders(LoggingEvent event) { 13 int writes = 0; 14 15 for(Category c = this; c != null; c=c.parent) { 16 // Protected against simultaneous call to addAppender, removeAppender,... 17 synchronized(c) { 18 if(c.aai != null) { 19 writes += c.aai.appendLoopOnAppenders(event); 20 } 21 if(!c.additive) { 22 break; 23 } 24 } 25 } 26 27 if(writes == 0) { 28 repository.emitNoAppenderWarning(this); 29 } 30 }
3.以WriterAppender(写入IO流)实例为例,append()方法会先检查是否有Layout,appender是否关闭等,subAppend实现打印。
1 /** 2 This method is called by the {@link AppenderSkeleton#doAppend} 3 method. 4 5 <p>If the output stream exists and is writable then write a log 6 statement to the output stream. Otherwise, write a single warning 7 message to <code>System.err</code>. 8 9 <p>The format of the output will depend on this appender's 10 layout. 11 12 */ 13 public 14 void append(LoggingEvent event) { 15 16 // Reminder: the nesting of calls is: 17 // 18 // doAppend() 19 // - check threshold 20 // - filter 21 // - append(); 22 // - checkEntryConditions(); 23 // - subAppend(); 24 25 if(!checkEntryConditions()) { 26 return; 27 } 28 subAppend(event); 29 }
4.subAppend()首先格式化打印信息,再判断是否忽略异常信息,如果不忽略,调用getThrowableStrRep()得到对战信息,打印。最后看是否需要立即刷新输出。
其中一些类和方法没有看懂,只能跟下流程 以后继续^_^
End……