JDK1.4自带日志器详解

sun公司在JDK1.4中自行开发了一个日志器,与之相关的类都被组织在java.util.logging包中。其中最重要的就是Logger类,它的实例可以帮助我们实现记录日志信息。

我们经常用的以下两步操作便可以实现记录日志信息:

       Logger log = Logger.getLogger("日志名");

       log.info("要记录的信息");

那么,这简单的两步操作的背后又做了些什么呢?

下面我们看一下Logger.getLogger(...)方法的实现:

public static synchronized Logger getLogger(String name) {
 LogManager manager = LogManager.getLogManager();
 Logger result = manager.getLogger(name);
 if (result == null) {
     result = new Logger(name, null);
     manager.addLogger(result);
     result = manager.getLogger(name);
 }
 return result;
}

从中我们可以发现,首先它调用LogManager类的静态方法getLogManager()。LogManager类代表一个日志管理器,所有的日志器都被它以树形的方式维护和管理着。getLogManager()的作用是将JRE_HOME/lib/logging.properties日志配置文件读入内存中,并返回LogManager类中定义的一个静态字段,名为manager,类型为LogManager。这个manager字段是在JVM加载LogManager类时被初始化,同时树的根结点(RootLogger)也是在此时被建立并放到manager中的。
JDK1.4自带日志器详解
manager.getLogger(name)方法是从manager维护和管理的日志器树上找出与这个name对应的日志器。接着判断result是否存在,如果不存在,就会新建一个日志器,并把它加到日志器树上去。如何确定它的父结点呢?根据这个name 。它的写法,应该是parent.child。当你只写child时,它就会被加到根结点下。

总体来讲Logger.getLogger(name)的作用是:

加载配置文件

获取全局日志管理器

从日志管理器维护的日志器树上查找与name对应的日志器,没有就新建并加到日志器树上。


再谈一下Logger如何将信息记录出去,Logger定义info(),debug()等,记录不同级别信息的方法,操作过程都大同小异,下面用info(String msg)举例说明一下:要记住的一点就是,向外记录信息是按照从子日志器到父日志器的过程

首先,构造一个LogRecord实例,这个实例除了保存msg以外,还通过访问堆栈,获取调用info()方  法的方法名,以及所在类。因此日志记录的格式为:日期 时间 所在类全名 方法名 msg

然后,通过获取此日志器的Handler,向外记录信息。利用log.setHandler(Handler的具体实现类的实例)可以为其设置Handler。Hander是一个抽象类,主要的作用就是通过其内部的publish()方法向外记录信息。除了Sun为我们准备好的ConsoleHandler和FileHandler以外,我们也可以自定义一个Handler。

最后,再处理它的父日志器,直至到达根结点为至。

*这也就是为什么,我们不为当前Log设置Hadler时, msg也会被记录出去的原因,因为根结点处理这个msg,并且根结点的handler来自配置文件JRE_HOME/lib/logging.properties中的配置。

另外,日志器设有过滤功能

你可能感兴趣的:(jvm,jdk,manager,String,null,sun)