您的位置:首页 > 其它

当我们在用LoggerFactory.getLogger(xyz.class)时我们在干什么

2015-04-17 11:09 423 查看
我们在使用logback一类的logging system的时候

总是在代码的前面部分放上这段代码private final Logger log = LoggerFactory.getLogger(AdController.class

这段代码调用了org.slf4j.LoggerFactory line:280

public static Logger getLogger(Class clazz) {
return getLogger(clazz.getName());
}


public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}


进入 ch.qos.logback.classic.LoggerContext line:105

Logger childLogger = (Logger) loggerCache.get(name);
loggerCache定义处

private Map<String, Logger> loggerCache;


初始化代码

public LoggerContext() {
super();
this.loggerCache = new ConcurrentHashMap<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;
this.frameworkPackages = new ArrayList<String>();
}


可以看到logger里通过name获取logger的实际上是访问了loggerCache这个支持高并发的hashmap.

以下50行代码 做了最重要的工作,请大家仔细阅读,就会明白了.其实很简单.

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 = LoggerNameUtil.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;
}
}
}
如果获取不了,就进入一个循环遍历

比如 我们给的name是com.colamachine.calendar.CalendarService

那么他会第一次会去找com 如果没有com就创建com的logger

再去寻找com.colamachine 同上创建

再去找并创建com.colamachine.calendar

再去找并创建com.colamachine.calendar.CalendarService.

好看完了代码,这只是我一厢情愿的猜测.现在来开始

果然如此

这样的机制 在内存的开销上是否过大

对于只有6个模块的小系统,轻轻松松的mapsize达到了532个
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: