poniedziałek, 27 października 2014

log4j 1.x - How appending log messages works - deep dive

All source code listings comes from 1.2.17

Once Logger.info(String) invoked there is the following implementation underneath

// org.apache.log4j.Category
661  public
662  void info(Object message) {
663    if(repository.isDisabled(Level.INFO_INT))
664      return;
665    if(Level.INFO.isGreaterOrEqual(this.getEffectiveLevel()))
666      forcedLog(FQCN, Level.INFO, message, null);
667  }
The repository object is of Hierarchy type which is specialized in retrieving loggers by name and maintaining hierarchy of loggers. FQCN - is fully qualified name of the calling category class After couple of self-explanatory checks we've got forcedLog(String,Priority,Object,Throwable) method called which creates a new logging event and call the appenders.
//org.apache.log4j.Category
389  protected
390  void forcedLog(String fqcn, Priority level, Object message, Throwable t) {
391    callAppenders(new LoggingEvent(fqcn, this, level, message, t));
392  }
At this point lets stop a while with LoggingEvent object. The LoggingEvent is a container object gathering calling category class name, actual message, optional throwable and timestamp. Timestamp can be passed in to the constructor, or is initialized with System.currentTimeMillis() during creation. It will be used by appenders for various reasons before eventually get them logged (eg. filtering). The loggingEvent is passed to callAppenders method:
//org.apache.log4j.Category
198 public
199  void callAppenders(LoggingEvent event) {
200    int writes = 0;
201
202    for(Category c = this; c != null; c=c.parent) {
203      // Protected against simultaneous call to addAppender, removeAppender,...
204      synchronized(c) {
205 if(c.aai != null) {
206   writes += c.aai.appendLoopOnAppenders(event);
207 }
208 if(!c.additive) {
209   break;
210 }
211      }
212    }
213
214    if(writes == 0) {
215      repository.emitNoAppenderWarning(this);
216    }
217  }
It goes through all the parent categories (loggers) ending with RootLogger inherently having no parent. Usually the root logger is the one having appenders. Field aai (of AppenderAttachableImpl type) is used to kept list of appenders.
// org.apache.log4j.helpers.AppenderAttachableImpl
57  public
58  int appendLoopOnAppenders(LoggingEvent event) {
59    int size = 0;
60    Appender appender;
61
62    if(appenderList != null) {
63      size = appenderList.size();
64      for(int i = 0; i < size; i++) {
65 appender = (Appender) appenderList.elementAt(i);
66 appender.doAppend(event);
67     }
68   }    
69   return size;
70  }
That is all from the core side. Now the actual appenders goes into play.

Brak komentarzy:

Prześlij komentarz