跳到主要内容

Java 日志记录

提示
  1. 日志记录框架:Java 提供 java.util.logging 包内置的日志记录框架,支持使用第三方框架如 Log4j。
  2. 核心组件:日志记录包括 Logger, Filter, HandlerFormatter 组件,实现了日志消息的创建、筛选、处理和格式化。
  3. 日志级别和管理:提供不同的日志级别,如 SEVERE, WARNING, INFO 等,以及 LogManager 来维护全局日志配置。

Java 允许我们通过日志记录过程创建和捕获日志消息和文件。

在 Java 中,日志记录需要框架和 API。Java 在 java.util.logging 包中内置了一个日志记录框架。

我们也可以使用第三方框架,如 Log4j、Logback 等,来进行日志记录。

Java 日志记录组件

下图展示了 Java 日志记录 API (java.util.logging) 的核心组件和控制流程。

Java 日志记录 API 的控制流程

1. 记录器(Logger)

Logger 类提供了用于日志记录的方法。我们可以实例化 Logger 类的对象,并调用其方法进行日志记录。

举个例子。

Logger logger = Logger.getLogger("newLoggerName");

Logger 类的 getLogger() 方法用于查找或创建新的 Logger。字符串参数定义了记录器的名称。

这里,这个方法会创建一个新的 Logger 对象或返回一个具有相同名称的现有 Logger

通常习惯在当前类后定义 Logger,使用 class.getName()

Logger logger = Logger.getLogger(MyClass.class.getName());

注意: 如果传递的名称是 null,此方法将抛出 NullPointerException

每个 Logger 都有一个确定日志消息重要性的级别。有 7 个基本日志级别:

日志级别 (从高到低)用途
SEVERE严重故障
WARNING警告消息,潜在问题
INFO一般运行时信息
CONFIG配置信息
FINE一般开发者信息(追踪消息)
FINER详细开发者信息(追踪消息)
FINEST高度详细的开发者信息(追踪消息)
OFF关闭所有级别的日志记录(不捕获任何内容)
ALL打开所有级别的日志记录(捕获所有内容)

除了两个特殊的日志级别 OFFALL,每个日志级别都有一个整数值来确定它们的严重程度。

记录消息

默认情况下,前三个日志级别总是被记录。要设置不同的级别,我们可以使用以下代码:

logger.setLevel(Level.LogLevel);

// 例如
logger.setLevel(Level.FINE);

在这个例子中,只有 FINE 级别及以上的日志被设置为记录。所有其他日志消息都被丢弃。

现在要记录一条消息,我们使用 log() 方法。

logger.log(Level.LogLevel, "log message");

// 例子
logger.log(Level.INFO, "这是 INFO 级别的日志消息");

还有一些快捷方法用于在所需级别记录日志。

logger.info("这是 INFO

级别的日志消息");
logger.warning("这是 WARNING 级别的日志消息");

所有通过设置的日志级别的日志请求随后会被转发到 LogRecord

注意: 如果记录器的级别被设置为 null,它的级别将从其父记录器继承,依此类推。

2. 过滤器(Filters)

如果存在过滤器,它决定是否应该转发 LogRecord。顾名思义,它根据特定标准过滤日志消息。

只有当 LogRecord 通过指定标准,才会从记录器传递到日志处理器,从日志处理器传递到外部系统。

// 设置过滤器
logger.setFilter(filter);

// 获取过滤器
Filter filter = logger.getFilter();

3. 处理器(Handlers)/附加器(Appenders)

日志处理器或附加器接收 LogRecord 并将其输出到不同的目标。

Java SE 提供了 5 个内置处理器:

处理器用途
StreamHandler写入到 OutputStream
ConsoleHandler写入到控制台
FileHandler写入到文件
SocketHandler写入到远程 TCP 端口
MemoryHandler写入到内存

处理器可以将 LogRecord 传递给过滤器,以再次确定是否可以转发到外部系统。

要添加新的处理器,我们使用以下代码:

logger.addHandler(handler);

// 示例
Handler handler = new ConsoleHandler();
logger.addHandler(handler);

要移除处理器,我们使用以下代码:

logger.removeHandler(handler);

// 示例
Handler handler = new ConsoleHandler();
logger.addHandler(handler);
logger.removeHandler(handler);

一个记录器可以有多个处理器。要获取所有处理器,我们使用以下代码:

Handler[] handlers = logger.getHandlers();

4. 格式化器(Formatters)

处理器还可以使用 FormatterLogRecord 对象格式化为字符串,然后输出到外部系统。

Java SE 有两个内置 Formatter

格式化器用途
SimpleFormatterLogRecord 格式化为字符串
XMLFormatterLogRecord 格式化为 XML 形式

我们可以使用以下代码来格式化处理器:

// 格式化为字符串形式
handler.setFormatter(new SimpleFormatter());

// 格式化为 XML 形式
handler.setFormatter(new XMLFormatter());

日志管理器(LogManager)

LogManager 对象跟踪全局日志信息。它读取并维护日志配置和记录器实例。

日志管理器是一个单例,这意味着只实例化一个它的实例。

要获取日志管理器实例,我们使用以下代码:

LogManager manager = LogManager.getLogManager();

日志记录的优势

以下是 Java 中日志记录的一些优势。

  • 帮助监控程序流程
  • 帮助捕获可能发生的任何错误
  • 提供问题诊断和调试的支持