final Logger root; private int size; private int noAppenderWarning = 0; final private List<LoggerContextListener> loggerContextListenerList = new ArrayList<LoggerContextListener>();
// We want loggerCache to be synchronized so Hashtable is a good choice. In // practice, it performs a little faster than the map returned by // Collections.synchronizedMap at the cost of a very slightly higher memory // footprint. private Hashtable<String, Logger> loggerCache;
private LoggerContextVO loggerContextRemoteView; private final TurboFilterList turboFilterList = new TurboFilterList(); private boolean packagingDataEnabled = true;
private int maxCallerDataDepth = ClassicConstants.DEFAULT_MAX_CALLEDER_DATA_DEPTH;
public LoggerContext() { super(); this.loggerCache = new Hashtable<String, Logger>(); this.loggerContextRemoteView = new LoggerContextVO(this); this.root = new Logger(Logger.ROOT_LOGGER_NAME, null, this); this.root.setLevel(Level.DEBUG); loggerCache.put(Logger.ROOT_LOGGER_NAME, root); initEvaluatorMap(); size = 1; }
这个方法基本上是只会调用一次的,在StaticLoggerBinder里
1
private LoggerContext defaultLoggerContext = new LoggerContext();
在构造LoggerContext的时候,对上面提到的字段进行了初始化,并创建了根Logger
1 2 3 4 5 6 7 8 9 10
/** * A new instance of LoggerContextRemoteView needs to be created each time the * name or propertyMap (including keys or values) changes. */ private void syncRemoteView() { loggerContextRemoteView = new LoggerContextVO(this); for (Logger logger : loggerCache.values()) { logger.buildRemoteView(); } }
final FilterReply getTurboFilterChainDecision_0_3OrMore(final Marker marker, final Logger logger, final Level level, final String format, final Object[] params, final Throwable t) { if (turboFilterList.size() == 0) { return FilterReply.NEUTRAL; } return turboFilterList.getTurboFilterChainDecision(marker, logger, level, format, params, t); }
public final Logger getLogger(final String name) {
if (name == null) { throw new IllegalArgumentException("name argument cannot be null"); }
// if we are asking for the root logger, then let us return it without // wasting time if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) { return root; }
int i = 0; Logger logger = root;
// check if the desired logger exists, if it does, return it // without further ado. Logger childLogger = (Logger) loggerCache.get(name); // if we have the child, then let us return it without wasting time if (childLogger != null) { return childLogger; }
// if the desired logger does not exist, them create all the loggers // in between as well (if they don't already exist) String childName; while (true) { int h = Logger.getSeparatorIndexOf(name, i); if (h == -1) { childName = name; } else { childName = name.substring(0, h); } // move i left of the last point i = h + 1; synchronized (logger) { childLogger = logger.getChildByName(childName); if (childLogger == null) { childLogger = logger.createChildByName(childName); loggerCache.put(childName, childLogger); incSize(); } } logger = childLogger; if (h == -1) { return childLogger; } } }
上面的getLogger(String name)方法,就是创建Logger的关键,详细解读一下:
1、如果name是null,抛出异常,不过这个情况基本是不会发生的
1 2 3
if (name == null) { throw new IllegalArgumentException("name argument cannot be null"); }
2、如果请求的是ROOT Logger,那么就直接返回root
1 2 3 4 5
// if we are asking for the root logger, then let us return it without // wasting time if (Logger.ROOT_LOGGER_NAME.equalsIgnoreCase(name)) { return root; }
// check if the desired logger exists, if it does, return it // without further ado. Logger childLogger = (Logger) loggerCache.get(name); // if we have the child, then let us return it without wasting time if (childLogger != null) { return childLogger; }
// if the desired logger does not exist, them create all the loggers // in between as well (if they don't already exist) String childName; while (true) { int h = Logger.getSeparatorIndexOf(name, i); if (h == -1) { childName = name; } else { childName = name.substring(0, h); } // move i left of the last point i = h + 1; synchronized (logger) { childLogger = logger.getChildByName(childName); if (childLogger == null) { childLogger = logger.createChildByName(childName); loggerCache.put(childName, childLogger); incSize(); } } logger = childLogger; if (h == -1) { return childLogger; } }