Java 日志入门

更新于 2025-12-30

baeldung 2024-05-11

1. 概述

日志是理解和调试程序运行时行为的有力工具。日志能够捕获并持久化重要数据,使其在任意时间点都可用于分析。

本文将讨论最流行的 Java 日志框架——Log4j 2 和 Logback,以及它们的前身 Log4j,并简要介绍 SLF4J(一个为不同日志框架提供统一接口的日志门面)。

2. 启用日志

本文讨论的所有日志框架都基于 Logger(记录器)Appender(输出目标)Layout(格式布局) 的概念。在项目中启用日志通常包括以下三个通用步骤:

  1. 添加所需依赖库
  2. 配置日志
  3. 在代码中插入日志语句

接下来的章节将分别介绍每个框架的具体实现方式。

3. Log4j 2

Log4j 2 是 Log4j 日志框架的新一代改进版本。其最引人注目的改进是支持异步日志记录。使用 Log4j 2 需要添加以下依赖库:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.6.1</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.6.1</version>
</dependency>

最新版本的 log4j-apilog4j-core 可分别在 此处此处 查找。

3.1 配置

Log4j 2 的配置基于主配置文件 log4j2.xml。首先需要配置的是 Appender(输出目标),它决定了日志消息的输出位置,例如控制台、文件、Socket 等。

Log4j 2 提供了多种 Appender,具体信息可参考 官方文档

下面是一个简单的配置示例:

<Configuration status="debug" name="baeldung" packages="">
    <Appenders>
        <Console name="stdout" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %p %m%n"/>
        </Console>
    </Appenders>
</Configuration>
  • 每个 Appender 可以指定名称,例如将 name="stdout" 改为 name="console"
  • <PatternLayout> 元素定义了日志消息的格式:
    • %d:日期格式
    • %p:日志级别
    • %m:日志消息内容
    • %n:换行符

更多格式说明请参阅 Log4j 2 官方文档

最后,要启用一个或多个 Appender,需将其添加到 <Loggers> 节点中:

<Loggers> 
    <Root level="error">
        <AppenderRef ref="stdout"/>
    </Root>
</Loggers>

3.2 文件日志

有时需要将日志写入文件,为此可在配置中添加一个 File 类型的 Appender:

<Appenders>
    <File name="fout" fileName="baeldung.log" append="true">
        <PatternLayout>
            <Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n</Pattern>
        </PatternLayout>
    </File>
</Appenders>

File Appender 的常用参数包括:

  • fileName:日志文件名
  • append:默认为 true,表示追加写入而非覆盖
  • PatternLayout:与控制台日志相同的格式配置

要启用该文件 Appender,需将其加入 <Root> 节点:

<Root level="INFO">
    <AppenderRef ref="stdout" />
    <AppenderRef ref="fout"/>
</Root>

3.3 异步日志

若希望启用 Log4j 2 的异步日志功能,需在 pom.xml 中添加 LMAX Disruptor 库(一种无锁线程间通信库):

<dependency>
    <groupId>com.lmax</groupId>
    <artifactId>disruptor</artifactId>
    <version>3.3.4</version>
</dependency>

最新版本的 Disruptor 可在 Maven Central 查询。

启用异步日志有两种方式:

  1. 在配置中使用 <AsyncRoot> 替代 <Root>
<AsyncRoot level="DEBUG">
    <AppenderRef ref="stdout" />
    <AppenderRef ref="fout"/>
</AsyncRoot>
  1. 或通过设置系统属性:
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

更多异步日志配置和性能对比可参考 Log4j 2 官方文档

3.4 使用示例

以下是一个使用 Log4j 2 的简单示例:

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

public class Log4jExample {

    private static Logger logger = LogManager.getLogger(Log4jExample.class);

    public static void main(String[] args) {
        logger.debug("Debug log message");
        logger.info("Info log message");
        logger.error("Error log message");
    }
}

运行后,日志将同时输出到控制台和 baeldung.log 文件中:

2016-06-16 17:02:13 INFO  Info log message
2016-06-16 17:02:13 ERROR Error log message

如果将根日志级别设为 ERROR

<Root level="ERROR">
    <AppenderRef ref="stdout" />
</Root>

则输出仅包含错误日志:

2016-06-16 17:02:13 ERROR Error log message

此外,logger.error() 还可用于记录异常:

try {
    // 可能抛出异常的代码
} catch (Exception e) {
    logger.error("Error log message", e);
}

3.5 包级别配置

假设你希望对特定包(如 com.baeldung.log4j2)启用 TRACE 级别日志,而其他包仍保持 INFO 级别。

由于 TRACE 级别低于全局 INFO,需在 <Root> 之前添加专用 <Logger> 配置:

<Logger name="com.baeldung.log4j2" level="trace">
    <AppenderRef ref="stdout"/>
</Logger>

此时,该包下的日志输出将包含所有级别:

2016-06-16 17:02:13 TRACE Trace log message
2016-06-16 17:02:13 DEBUG Debug log message
2016-06-16 17:02:13 INFO  Info log message
2016-06-16 17:02:13 ERROR Error log message

4. Logback

Logback 是由 Log4j 原作者开发的新一代日志框架,旨在改进 Log4j。它比 Log4j 功能更丰富,许多特性后来也被引入 Log4j 2。

要使用 Logback,只需添加以下依赖:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

该依赖会自动引入 logback-coreslf4j-api。最新版本可在 Maven Central 查询。

4.1 配置示例

Logback 的配置文件通常为 logback.xml,示例如下:

<configuration>
  <!-- 控制台输出 -->
  <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
      <Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n</Pattern>
    </layout>
  </appender>

  <!-- 文件输出 -->
  <appender name="fout" class="ch.qos.logback.core.FileAppender">
    <file>baeldung.log</file>
    <append>false</append>
    <encoder>
      <pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n</pattern>
    </encoder>
  </appender>

  <!-- 为特定包设置日志级别 -->
  <logger name="com.baeldung.log4j" level="TRACE"/>

  <root level="INFO">
    <appender-ref ref="stdout" />
    <appender-ref ref="fout" />
  </root>
</configuration>

注意:Logback 使用 SLF4J 作为其原生 API。

4.2 SLF4J

SLF4J(Simple Logging Facade for Java)为各种 Java 日志框架提供了统一的接口抽象。它作为一个“门面”,允许开发者通过标准化 API 访问底层日志实现。

Logback 原生支持 SLF4J。以下是使用 Logback + SLF4J 的代码示例:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Log4jExample {

    private static Logger logger = LoggerFactory.getLogger(Log4jExample.class);

    public static void main(String[] args) {
        logger.debug("Debug log message");
        logger.info("Info log message");
        logger.error("Error log message");
    }
}

输出结果与前述示例一致。

5. Log4j(经典版)

Log4j 是早期广泛使用的日志框架,现已过时,但因其奠定了现代日志框架的基础,仍值得了解。

其配置方式与 Log4j 2 类似。

5.1 配置

首先添加依赖:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

最新(也是最终)版本可在 Maven Central 查询。

以下是一个仅包含控制台输出的简单配置:

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration debug="false">

    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" 
              value="%d{yyyy-MM-dd HH:mm:ss} %p %m%n" />
        </layout>
    </appender>

    <root>
        <level value="INFO" />
        <appender-ref ref="stdout" />
    </root>

</log4j:configuration>
  • <log4j:configuration debug="false"> 中的 debug 属性控制是否输出 Log4j 自身的调试信息。

5.2 使用示例

配置完成后,即可在代码中使用:

import org.apache.log4j.Logger;

public class Log4jExample {
    private static Logger logger = Logger.getLogger(Log4jExample.class);

    public static void main(String[] args) {
        logger.debug("Debug log message");
        logger.info("Info log message");
        logger.error("Error log message");
    }
}

6. 结论

本文展示了如何使用 Log4j、Log4j 2 和 Logback 三种主流 Java 日志框架,并提供了各自的简单配置示例。通过合理配置日志级别、输出目标和格式,开发者可以高效地监控和调试应用程序。