您的位置:首页 > 编程语言 > Java开发

关于Logger的结构

2015-07-13 18:13 946 查看
早天看到一遍关于JDK日志层级的文章,原文:
http://tutorials.jenkov.com/java-logging/logger-hierarchy.html
一路被这个文章讲的晕头转向。什么 forward,Passed,propagated等等。
JDK为什么把他设计的那么复杂,今天看一下JDK的代码。发现他测试的结果是对的,但讲法的差强人意。



日志结构却如上图树形所示,但Logger之间的父子关系是通过单独的索引结构表示的。如上图红色线表示logger(com.jenkoe.web)的父logger为rootlogger,在寻祖的过程中,中间结点若是虚结点,由直接跳过。这就是文件所说的:
if you do create a
Logger
like this:
Logger logger  = Logger.getLogger("com.jenkov.web");
... and call
getParent()
method, you will get the
Logger
with the name
"".
一旦中间的结点有值(由虚变实)需要更新其孩子结点的父索引(具体可看LogContext.addLocalLoader源码)。

再说Filter的传递问题,文件讲得太不好理解有两个点:
accept or reject 只发生在当前logger的filter上,若当前logger无filter,则accept。

若当前logger accept这个日志,则传播到上层logger,一直到根。

太晦涩,看代码:

public void log(LogRecord record) {
if (!isLoggable(record.getLevel())) {
return;
}
Filter theFilter = filter;
if (theFilter != null && !theFilter.isLoggable(record)) {
return;
}

// Post the LogRecord to all our Handlers, and then to
// our parents' handlers, all the way up the tree.

Logger logger = this;
while (logger != null) {
final Handler[] loggerHandlers = isSystemLogger
? logger.accessCheckedHandlers()
: logger.getHandlers();

for (Handler handler : loggerHandlers) {
handler.publish(record);
}

final boolean useParentHdls = isSystemLogger
? logger.useParentHandlers
: logger.getUseParentHandlers();

if (!useParentHdls) {
break;
}

logger = isSystemLogger ? logger.parent : logger.getParent();
}
}
只用调用当前logger的filter,则所谓的传播是useParentHandler属性在起做作用,若为true,则递归调用祖辈logger的Handler,没有父logger的filter什么事。

在下面关于日志级别的问题,正如上面的代码。只在当前logger里进行了级别检查, 也没传播与否的说法。
文中:
Logger logger      = Logger.getLogger("");
Logger logger1     = Logger.getLogger("1");
Logger logger1_2   = Logger.getLogger("1.2");

logger1  .setLevel(Level.WARNING);
logger1_2.setLevel(Level.INFO);

logger     .info("msg:");
logger1    .info("msg: 1");
logger1_2  .info("msg: 1.2");
The result of this code is that the
INFO
message logged on the bottom
Logger
(named
1.2
) is now logged, but it is still not propagated up the hierarchy. Well, it is, but the middle
Logger
filters it out, because the middle
Logger
has a log level of
WARNING
set. Thus, the message is not logged by the middle
Logger
nor propagated up the hierarchy.

不知道作者是否代码粘错了。这里没有propagated, 并不是middle
Logger的level问题,而是因为  middle Logger和
bottom
Logger
都没有指定handler。最后全都传导到Root logger(它有默认的handler)。
若代码改成:

Logger logger      = Logger.getLogger("");
Logger logger1     = Logger.getLogger("1");
Logger logger1_2   = Logger.getLogger("1.2");

logger1    .addHandler(new ConsoleHandler());
logger1_2  .addHandler(new ConsoleHandler());
logger1  .setLevel(Level.WARNING);
logger1_2.setLevel(Level.INFO);

logger     .info("msg:");
logger1    .info("msg: 1");
logger1_2  .info("msg: 1.2");
结果就是:
九月 05, 2017 4:29:15 下午 java.util.logging.LogManager$RootLogger log
信息: msg:
九月 05, 2017 4:29:15 下午 guojje.SAPITest main
信息: msg: 1.2
九月 05, 2017 4:29:15 下午 guojje.SAPITest main
信息: msg: 1.2
九月 05, 2017 4:29:15 下午 guojje.SAPITest main
信息: msg: 1.2
所以很多费解的文章都是有问题的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java logger filter h