自Java 1.4开始,JDK提供了一个日志框架包 java.util.logging。
JDK 日志框架主要包括如下几个部件:
- Logger:日志记录对象。用于记录日志信息。
- Handler:用于处理日志信息的输出。在 Handler 类中,可以决定日志是输出到文件中还是控制台中(相当于log4j中的appender)。
- Filter:用于过滤日志。在 Filter 类中,可以根据日志级别或者某种条件来决定是否输出该日志。这样达到去除冗余信息的目的。
- Formatter:用于格式化日志信息。该类可以将日志文本格式化成 XML 或者 HTML 的格式,这完全依赖于具体的实现。
- Level:用于表示日志的级别。 JDK 日志框架默认有如下级别:SEVERE(最高值) 、WARNING 、INFO 、CONFIG 、FINE 、FINER 、FINEST(最低值)、ALL(记录所有信息) OFF(不记录任何级别信息)。
默认情况下,JDK的LogManager会在JRE目录下的"lib/logging.properties"这个文件中读取配置。
对于程序而言,它的 Logger 对象首先会判断日志的级别是否满足输出级别的要求,然后将满足级别要求的日志消息交给所配置的 Handler 对象来处理,如果日志对象配置了一个 Filter 对象,那么 Filter 对象将会对日志信息做一次过滤。 Handler 对象接受到日志消息后,根据其所配置的格式化类 Formatter 来改变日志的格式,根据所配置的 Filter 对象和 Level 对象来再次过滤日志信息,最后输出到该种 Handler 对象所指定的输出位置中,该输出位置可以是控制台,文件,网络 socket 甚至是内存缓冲区。其架构模型如下图所示:
JDK 提供了如下几种默认支持的 Handler 类:
- ConsoleHandler: 输出日志到控制台中
- FileHandler:输出日志到指定文件中
- MemoryHandler:输出日志到内存缓冲区中,当一定的条件满足的时候(如某种关键字的日志信息)再将缓冲区中的日志输出
- SocketHandler:输出日志到网络 socket 中
- StreamHandler:输出日志到输入输出流对象中
同时 JDK 日志框架也不失其灵活性,你可以定制自己所需要的 Handler,将日志按照自定义的需求输出到不同的位置,同时 Formatter、Level 类都可以自定义扩展。
LogManager类初始化的时候会创建一个根日志 RootLogger。
每个 Logger 都跟踪一个“父”Logger,也就是 Logger 名称空间中与其最近的现有祖先。
每个 Logger 都有一个与其相关的 "Level"。这反映了此 logger 所关心的最低 Level。如果将 Logger 的级别设置为 null,那么它的有效级别继承自父 Logger,这可以通过其父 Logger 一直沿树向上递归得到。
可以根据日志配置文件的属性来配置日志级别,在 LogManager 类的描述中对此有所说明。但是也可以通过调用 Logger.setLevel 方法动态地改变它。如果日志级别改变了,则此变化也会影响它的子 logger,因为任何级别为 null 的子 logger 的有效级别都继承自它的父 Logger。
对于每次日志记录调用,Logger 最初都依照 logger 的有效日志级别对请求级别(例如 SEVERE 或 FINE)进行简单的检查。如果请求级别低于日志级别,则日志记录调用将立即返回。