/** * The name of this logger */ private String name;
// The assigned levelInt of this logger. Can be null. private Level level;
// The effective levelInt is the assigned levelInt and if null, a levelInt is // inherited form a parent. private int effectiveLevelInt;
/** * The parent of this category. All categories have at least one ancestor * which is the root category. */ private Logger parent;
/** * The children of this logger. A logger may have zero or more children. */ private List<Logger> childrenList;
/** * It is assumed that once the 'aai' variable is set to a non-null value, it * will never be reset to null. it is further assumed that only place where * the 'aai'ariable is set is within the addAppender method. This method is * synchronized on 'this' (Logger) protecting against simultaneous * re-configuration of this logger (a very unlikely scenario). * * <p> * It is further assumed that the AppenderAttachableImpl is responsible for * its internal synchronization and thread safety. Thus, we can get away with * *not* synchronizing on the 'aai' (check null/ read) because * <p> * 1) the 'aai' variable is immutable once set to non-null * <p> * 2) 'aai' is getAndSet only within addAppender which is synchronized * <p> * 3) all the other methods check whether 'aai' is null * <p> * 4) AppenderAttachableImpl is thread safe */ private transient AppenderAttachableImpl<ILoggingEvent> aai; /** * Additivity is set to true by default, that is children inherit the * appenders of their ancestors by default. If this variable is set to * <code>false</code> then the appenders located in the ancestors of this * logger will not be used. However, the children of this logger will inherit * its appenders, unless the children have their additivity flag set to * <code>false</code> too. See the user manual for more details. */ private boolean additive = true;
final transient LoggerContext loggerContext; // loggerRemoteView cannot be final because it may change as a consequence // of changes in LoggerContext LoggerRemoteView loggerRemoteView;
private final boolean isRootLogger() { // only the root logger has a null parent return parent == null; }
这个方法用来判断一个Logger是否是根Logger
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
Logger getChildByName(final String childName) { if (childrenList == null) { return null; } else { int len = this.childrenList.size(); for (int i = 0; i < len; i++) { final Logger childLogger_i = (Logger) childrenList.get(i); final String childName_i = childLogger_i.getName();
if (childName.equals(childName_i)) { return childLogger_i; } } // no child found return null; } }
public synchronized void setLevel(Level newLevel) { if (level == newLevel) { // nothing to do; return; } if (newLevel == null && isRootLogger()) { throw new IllegalArgumentException( "The level of the root logger cannot be set to null"); }
if (childrenList != null) { int len = childrenList.size(); for (int i = 0; i < len; i++) { Logger child = (Logger) childrenList.get(i); // tell child to handle parent levelInt change child.handleParentLevelChange(effectiveLevelInt); } } // inform listeners loggerContext.fireOnLevelChange(this, newLevel); }
/** * This method is invoked by parent logger to let this logger know that the * prent's levelInt changed. * * @param newParentLevel */ private synchronized void handleParentLevelChange(int newParentLevelInt) { // changes in the parent levelInt affect children only if their levelInt is // null if (level == null) { effectiveLevelInt = newParentLevelInt;
// propagate the parent levelInt change to this logger's children if (childrenList != null) { int len = childrenList.size(); for (int i = 0; i < len; i++) { Logger child = (Logger) childrenList.get(i); child.handleParentLevelChange(newParentLevelInt); } } } }
这2个方法是用来改变Logger的生效级别,并且连带改变子Logger的生效级别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
Logger createChildByName(final String childName) { int i_index = getSeparatorIndexOf(childName, this.name.length() + 1); if (i_index != -1) { throw new IllegalArgumentException("For logger [" + this.name + "] child name [" + childName + " passed as parameter, may not include '.' after index" + (this.name.length() + 1)); }
if (childrenList == null) { childrenList = new ArrayList<Logger>(DEFAULT_CHILD_ARRAY_SIZE); } Logger childLogger; childLogger = new Logger(childName, this, this.loggerContext); childrenList.add(childLogger); childLogger.effectiveLevelInt = this.effectiveLevelInt; return childLogger; }
/** * The next methods are not merged into one because of the time we gain by not * creating a new Object[] with the params. This reduces the cost of not * logging by about 20 nanoseconds. */
private final void filterAndLog_0_Or3Plus(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params, final Throwable t) {
private void buildLoggingEventAndAppend(final String localFQCN, final Marker marker, final Level level, final String msg, final Object[] params, final Throwable t) { LoggingEvent le = new LoggingEvent(localFQCN, this, level, msg, t, params); le.setMarker(marker); callAppenders(le); }
/** * Invoke all the appenders of this logger. * * @param event * The event to log */ public void callAppenders(ILoggingEvent event) { int writes = 0; for (Logger l = this; l != null; l = l.parent) { writes += l.appendLoopOnAppenders(event); if (!l.additive) { break; } } // No appenders in hierarchy if (writes == 0) { loggerContext.noAppenderDefinedWarning(this); } }
final private ReadWriteLock rwLock = new ReentrantReadWriteLock(); private final Lock r = rwLock.readLock(); private final Lock w = rwLock.writeLock();