Java Logging: Logger Hierarchy

Table of Contents

The Logger‘s used in your application are typically organized into a hierarchy, as mentioned elsewhere in this tutorial. This text will take a closer look at how this Logger hierarchy works.

When you create a Logger you pass a name to the Logger.getLogger() method. Here is an example:

Logger logger  = Logger.getLogger("com.jenkov.web");

In this example the name of the created Logger is com.jenkov.web.

The name indicates a hierarchy of Loggers. Each . (dot) in the name marks a level in the hierarchy. (Note: These levels are different from the log levels of the messages logged.). With the name com.jenkov.web the Loggerhas 3 parents, with these names:

""
"com"
"com.jenkov"

Here is a diagram illustrating the full hierarchy:

Java Logger Hierarchy Example

If you call the getParent() on the Logger created in the example above, you will get the Logger with the namecom.jenkov. If you call getParent() on that Logger you will get the Logger with the name com. The root of the hierarchy is the Logger with the empty string as name ("").

One thing to note is, that you need to create the Loggers in the hierarchy, before they exist. So, if you do create aLogger like this:

Logger logger  = Logger.getLogger("com.jenkov.web");

... and call getParent() method, you will get the Logger with the name "". The reason for this is, that none of the in-between Logger‘s in hierarchy have been created. You need to do the following to instantiate all theLogger‘s in the hierarchy:

Logger logger  = Logger.getLogger("");
Logger logger1 = Logger.getLogger("com");
Logger logger2 = Logger.getLogger("com.jenkov");
Logger logger3 = Logger.getLogger("com.jenkov.web");

Now, if you call getParent() on logger3, you will get the Logger with the name com.jenkov. The parent of that Logger is named com etc.

Filters and Handlers in the Logger Hierarchy

When a message is passed to a Logger, the message is passed through the Logger‘s Filter, if the Loggerhas a Filter set. The Filter can either accept or reject the message. If the message is accepted, the message is forwarded to the Handler‘s set on the Logger. If no Filter is set, the message is always accepted.

If a message is accepted by the Filter, the message is also forwarded to the Handler‘s of the parentLogger‘s. However, when a message is passed up the hierarchy, the message is not passed through theFilter‘s of the parent Logger‘s. The Filter‘s are only asked to accept the message when the message is passed directly to the Logger, not when the message comes from a child Logger.

Here is a diagram illustrating the propagation of messages up the Logger hierarchy:

Java Logger Hierarchy Example

To show you this in effect I will illustrate it using a few code examples.

First, here is an example that creates 3 loggers in the hierarchy. A ConsoleHandler is assigned to 2 of them. The root Logger has a Handler by default, so it is not necessary to add a Handler to that. Then 3 messages are logged. One message via each Logger in the hierarchy. Here is the code:

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());

logger     .info("msg:");
logger1    .info("msg: 1");
logger1_2  .info("msg: 1.2");

The output in the log (console) of this code is:

14-01-2012 10:32:41 java.util.logging.LogManager$RootLogger log
INFO: msg:
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1.2
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1.2
14-01-2012 10:32:42 logging.LoggingExamples main
INFO: msg: 1.2

Notice how the first message is being logged only once, by the root Logger.

The second message is being logged twice: Once by the 1 Logger, and once by the root Logger.

The third message is being logged three times: Once by the 1.2 Logger, once by the 1 Logger, and once by the root Logger.

Now, lets try adding a filter to the middle Logger in the hierarchy, the Logger named 1. Here is the code with the added Filter:

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.setFilter(new Filter() {
    public boolean isLoggable(LogRecord record) {
    return false;
    }
    });

logger     .info("msg:");
logger1    .info("msg: 1");
logger1_2  .info("msg: 1.2");

With a Filter rejecting all messages set on the middle Logger, the output logged is this:

14-01-2012 11:33:21 java.util.logging.LogManager$RootLogger log
INFO: msg:
14-01-2012 11:33:21 logging.LoggingExamples main
INFO: msg: 1.2
14-01-2012 11:33:21 logging.LoggingExamples main
INFO: msg: 1.2
14-01-2012 11:33:21 logging.LoggingExamples main
INFO: msg: 1.2

Notice how the first message is still logged once, and the third message still logged three times, once by eachLogger in the hierarchy.

The second message, however, the message sent to the middle Logger is not logged at all. The Filter set on the middle Logger which always return false (meaning it never accepts any messages), filters out all messages logged via this Logger. Thus, the second message is never logged, nor propagated up the Logger hierarchy.

Notice though, that the message propagated up the hierarchy from the Logger named 1.2 is still logged by the middle Logger, and still forwarded up to the root Logger. The Filter set on the middle Logger does not touch propagated messages.

Log Levels of Loggers in the Hierarchy

As mentioned elsewhere in this tutorial you can set the log levels of messages to be logged, separately for eachLogger. If a Logger has a certain log level set, then all messages of less importance than the set log level is ignored. Additionally, all levels below the set log level are not propagated up the Logger hierarchy. That is a different from the behaviour of a Filter.

Here is a code example that shows a Logger hierarchy with 3 Logger‘s in, and with the middle logger (named 1) having a minimum log level of WARNING set.

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

logger1  .setLevel(Level.WARNING);

logger     .info("msg:");
logger1    .info("msg: 1");
logger1_2  .info("msg: 1.2");

The result of this is, that no messages logged to the middle logger of less importance than WARNING is logged, nor propagated up the hierarchy. The log level INFO is less important than WARNING, so the INFO message logged to the middle logger is ignored, and not propagated to the root logger.

Another peculiar result of the above code is, that the INFO message passed to the bottom Logger (named 1.2) is also ignored, and not propagated. The reason for this is, that the bottom Logger does not have a log level set, and thus inherits the level set on its parent in the Logger hierarchy. In other words, the bottom Logger inherits the log level set on the middle Logger.

The code example above is illustrated in this diagram:

Example of how log levels work in the Logger hierarchy.

Here is the output logged from the above code:

14-01-2012 13:25:32 java.util.logging.LogManager$RootLogger log
INFO: msg:

Only the message logged directly via the root Logger is actually logged.

In order to enable all INFO messages to be logged from the bottom Logger (named 1.2), even if the middleLogger has a log level of WARNING, we add the following to the code (in bold):

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 Loggerhas a log level of WARNING set. Thus, the message is not logged by the middle Logger nor propagated up the hierarchy.

The code example above is illustrated in this diagram:

Example of how log levels work in the Logger hierarchy.

The dashed line between the bottom and the middle Logger symbolizes, that only messages of WARNING or higher importance are propagated up the hierarchy.

Here is the output logged by the above code:

14-01-2012 13:30:27 java.util.logging.LogManager$RootLogger log
INFO: msg:
14-01-2012 13:30:27 logging.LoggingExamples main
INFO: msg: 1.2

The INFO message logged to the bottom Logger is logged, but not propagated.

The INFO message logged to the middle Logger is neither logged, nor propagated.

The INFO message logged to the root Logger is logged.

The specific log levels are covered in more detail in the text on Log Levels. The coverage here only serves to explain how the log level affects message propagation in the Logger hierarchy.

时间: 2024-10-03 23:04:15

Java Logging: Logger Hierarchy的相关文章

Java Logging: Logger

Table of Contents Logging Messages The log() Methods The logp() Methods The logrb() Methods The Last Log Methods Adding and Removing Handlers Setting a Log Filter Setting the Log Level Parent Logger Additional Methods The java.util.Logger class is th

【java】java自带的java.util.logging.Logger日志功能

偶然翻阅到一篇文章,注意到Java自带的Logger日志功能,特地来细细的看一看,记录一下. 1.Java自带的日志功能,默认的配置 ①Logger的默认配置,位置在JRE安装目录下lib中的logging.properties中 ②logging.properties日志文件内容如下: ############################################################ # Default Logging Configuration File # # You

java.util.logging.Logger使用具体解释

java.util.logging.Logger不是什么新奇东西了,1.4就有了,但是由于log4j的存在,这个logger一直沉默着,事实上在一些測试性的代码中,jdk自带的logger比log4j更方便. 一.创建Logger对象 static Logger getLogger(String name) 为指定子系统查找或创建一个 logger. static Logger getLogger(String name, String resourceBundleName) 为指定子系统查找或

java.util.logging.Logger基础

1. 定义 java.util.logging.Logger是Java自带的日志类,可以记录程序运行中所产生的日志.通过查看所产生的日志文件,可以分析程序的运行状况,出现异常时,分析及定位异常. 2.简单的例子 import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.Date; i

java.util.logging.Logger使用详解 (转)

http://lavasoft.blog.51cto.com/62575/184492/ ************************************************* java.util.logging.Logger使用详解 java.util.logging.Logger不是什么新鲜东西了,1.4就有了,可是因为log4j的存在,这个logger一直沉默着,其实在一些测试性的代码中,jdk自带的logger比log4j更方便. 一.创建Logger对象 static Lo

java.util.logging.Logger基础教程

从JDK1.4开始即引入与日志相关的类java.util.logging.Logger,但由于Log4J的存在,一直未能广泛使用.综合网上各类说法,大致认为: (1)Logger:适用于小型系统,当日志量过大时性能有待提升.好处在于JDK集成了此类,无需引入新包.且性能也在逐步改善当中,我认为一般而言,使用Logger即可. (2)Log4J:并发性较好,性能较强,适用于大型系统. 本文介绍java.util.logging.Logger的详细用法.    1.基本概念 Logger中有2个比较

通配置文件的方式控制java.util.logging.Logger日志输出

转自:http://zochen.iteye.com/blog/616151 简单的实现了下利用JDK中类java.util.logging.Logger来记录日志.主要在于仿照log4j方式用配置文件来配置日志的输出.网络上关于如何使用java.util.logging.Logger的文章很多,但是没有完整的如何通过配置配置文件来达到控制日志输出的资料.本文的目的在于此,欢迎拍砖.   上码... 1.首先封装了个LogManager.该类的主要作用就是static块中的代码,意在读取prop

java.util.logging.Logger 使用详解

概述: 第1部分 创建Logger对象 第2部分 日志级别 第3部分 Handler 第4部分 Formatter 第5部分 自定义 第6部分 Logger的层次关系 参考 第1部分 创建Logger对象 要使用J2SE的日志功能,首先要取得java.util.logging.Logger实例,这可以通过Logger类的两个静态getLogger()方法来取得: static Logger getLogger(String name) 查找或创建一个logger. static Logger g

java.util.logging.Logger 使用中关于时间格式的问题

java.util.logging.Logger类可以打印相关日志信息并将日志信息写入日志文件 tomcat7默认的日志格式输出方法是 java.util.logging.SimpleFormatter.format 如: Apr 11, 2018 4:11:48 PM tomcat8默认的日志格式输出方法是 org.apache.juli.OneLineFormatter 如: 12-Apr-2018 15:52:41.446 [logging.properties],该属性文件存在于java