一、对于java.util.logging的介绍
http://gceclub.sun.com.cn/Java_Docs/jdk6/html/zh_CN/api/java/util/logging/package-summary.html
1.自从jdk1.4才引入logging包
2.包结构分析
总体结构图
从以上总体结构图中可以看出以下几点:
a.LogManager创建并维护Logger的实例,同时LogManager也指定日志配置属性
b.Logger指定了某一日志层次Level
c.Logger包含了一个或多个Handler
d.Handler使用Formatter来格式化LogRecord
e.当Logger发送LogRecord到Handler时,会利用Filter来检查是否此日志记录满足条件
f.Logger中保留有Filter
g.Handler中保留有Filter
Handler关系
有几种Handler用于处理LogRecord记录
a.ConsoleHandler 发送到控制台日志
b.FileHandler 发送到文件
c.MemoryHandler 缓冲到内存中
d.SocketHandler 向Socket发送的处理
e.StreamHandler 基于流的日志处理
Formatter关系
SimpleFormatter 简单格式化
XMLFormatter XML格式化
设计的优点:
1).添加新的处理者十分容易(假如要将日志记录到DB中,可以写一个DBHandler类继承Handler类)
2).添加新的日志格式十分容易,只需要添加新的Formatter实现类即可
3.主要的类介绍
Level -- 表示日志的层次
各级别按降序排列如下:
Logger -- 用于记录日志
大多数 logger 输出方法都带有 "msg" 参数。此 msg 参数可以是一个原始值,也可以是一个本地化的键。在格式化期间,如果 logger 具有(或继承)一个本地化 ResourceBundle,并且 ResourceBundle 包含 msg 字符串的映射关系,那么用本地化值替换 msg 字符串。否则使用原来的 msg 字符串。
日志记录方法划分为 5 个主要类别:
一系列的 "log" 方法,这种方法带有日志级别、消息字符串,以及可选的一些消息字符串参数。
一系列的 "logp" 方法(即 "log precise"),其与 "log" 方法相似,但是带有显式的源类名称和方法名称。
一系列的 "logrb" 方法(即 "log with resource bundle"),其与 "logp" 方法相似,但是带有显式的在本地化日志消息中使用的资源包名称。
还有跟踪方法条目("entering" 方法)、方法返回("exiting" 方法)和抛出异常("throwing" 方法)的便捷方法。
最后,还有一系列在非常简单的情况下(如开发人员只想为给定的日志级别记录一条简单的字符串)使用的便捷方法。这些方法按标准级别名称命名("severe"、"warning"、"info" 等等),并带有单个参数,即一个消息字符串。
Logger 上执行的所有方法都是多线程安全的。
二、主要代码分析
以下是JDK14Logger用来记录日志的一段代码:
private void log( Level level, String msg, Throwable ex ) { Logger logger = getLogger(); if (logger.isLoggable(level)) { // Hack (?) to get the stack trace. Throwable dummyException=new Throwable(); StackTraceElement locations[]=dummyException.getStackTrace(); // Caller will be the third element String cname="unknown"; String method="unknown"; if( locations!=null && locations.length >2 ) { StackTraceElement caller=locations[2]; cname=caller.getClassName(); method=caller.getMethodName(); } if( ex==null ) { logger.logp( level, cname, method, msg ); } else { logger.logp( level, cname, method, msg, ex ); } } }
其中:为什么选locations[2]呢?比如:我的程序调用了debug用于记录异常日志,则调用链为:
YourApp->Logger.debug->Logger.log,则栈顶为Logger.log,为了记录是哪个类出的异常,所以应为locations[2]
另外,Jdk13LumberjackLogger实现基本上同于 JDK14Logger实现