SLF4J用户手册(谷歌翻译版)

本文翻译自slf4j官方用户手册,地址 SLF4J Manual

Java 的简单日志门面 (SLF4J) 用作各种日志框架的简单门面或抽象,例如 java.util.logging、logback 和 reload4j。 SLF4J 允许最终用户在部署时插入所需的日志框架。 请注意,启用 SLF4J 的库/应用程序意味着仅添加一个强制依赖项,即 slf4j-api-1.7.36.jar。

自 1.6.0 起 如果在类路径上没有找到绑定,那么 SLF4J 将默认为无操作实现。

自 1.7.0 起,Logger 接口中的打印方法现在提供接受可变参数而不是 Object[] 的变体。 此更改意味着 SLF4J 需要 JDK 1.5 或更高版本。 在底层,Java 编译器将方法中的可变参数部分转换为 Object[]。 因此,编译器生成的 Logger 接口在 1.7.x 中与其对应的 1.6.x 没有区别。 因此,SLF4J 版本 1.7.x 完全 100% 与 SLF4J 版本 1.6.x 兼容。

自 1.7.5 起,记录器检索时间显着改善。 鉴于改进的程度,强烈建议用户迁移到 SLF4J 1.7.5 或更高版本。

自 1.7.9 起,通过将 slf4j.detectLoggerNameMismatch 系统属性设置为 true,SLF4J 可以自动发现命名错误的记录器。

自 2.0.0 起, SLF4J API 版本 2.0.0 需要 Java 8 并引入了向后兼容的 fluent logging API。 通过向后兼容,我们的意思是不必更改现有的日志框架,以便用户从流畅的日志 API 中受益。

自 2.0.0 起,SLF4J API 版本 2.0.0 依赖 ServiceLoader 机制来查找其日志记录后端。 有关更多详细信息,请参阅相关的常见问题解答条目。

Hello World

按照编程传统的惯例,这里有一个示例,说明了使用 SLF4J 输出“Hello world”的最简单方法。 首先获取一个名为“HelloWorld”的记录器。 该记录器又用于记录消息“Hello World”。

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

public class HelloWorld {
  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}

要运行此示例,您首先需要下载 slf4j 发行版,然后将其解压缩。 完成后,将文件 slf4j-api-1.7.36.jar 添加到您的类路径中。

编译并运行 HelloWorld 将在控制台上打印以下输出。

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

打印此警告是因为在您的类路径上找不到 slf4j 绑定。 

将绑定添加到类路径后,警告就会消失。 假设您添加 slf4j-simple-1.7.36.jar 以便您的类路径包含:

  • slf4j-api-1.7.36.jar
  • slf4j-simple-1.7.36.jar

编译和运行 HelloWorld 现在将在控制台上产生以下输出。

0 [main] INFO HelloWorld - Hello World

典型使用模式

下面的示例代码说明了 SLF4J 的典型使用模式。 请注意第 15 行使用 {}-占位符。请参阅问题“什么是最快的记录方式?” 在常见问题解答中了解更多详细信息。

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

public class Wombat {
 
  final Logger logger = LoggerFactory.getLogger(Wombat.class);
  Integer t;
  Integer oldT;

  public void setTemperature(Integer temperature) {
   
    oldT = t;        
    t = temperature;

    logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);

    if(temperature.intValue() > 50) {
      logger.info("Temperature has risen above 50 degrees.");
    }
  }
} 

流式日志API

自 2.0.0 起 SLF4J API 版本 2.0.0 需要 Java 8 并引入了向后兼容的 fluent logging API。 通过向后兼容,我们的意思是不必更改现有的日志框架,以便用户从流畅的日志 API 中受益。

想法是使用 LoggingEventBuilder 逐个构建日志事件,并在事件完全构建后进行日志记录。 atTrace()、atDebug()、atInfo()、atWarn() 和 atError() 方法都是 org.slf4j.Logger 接口中的新方法,它们返回 LoggingEventBuilder 的实例。 对于禁用的日志级别,返回的 LoggingEventBuilder 实例什么都不做,从而保留了传统日志接口的纳秒级性能。

以下是几个使用示例:

该声明

logger.atInfo().log("Hello world.");

相当于:

logger.info("Hello world.");

以下日志语句在其输出中是等效的(对于默认实现):

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

public class Wombat {
 
  final Logger logger = LoggerFactory.getLogger(Wombat.class);
  Integer t;
  Integer oldT;

  public void setTemperature(Integer temperature) {
   
    oldT = t;        
    t = temperature;

    logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);

    if(temperature.intValue() > 50) {
      logger.info("Temperature has risen above 50 degrees.");
    }
  }
} 

流式日志API 允许将许多不同类型的数据规范到 org.slf4j.Logger 中,而不会在 Logger 接口中的方法数量上出现组合爆炸式增长。

现在可以传递多个Markers,使用Supplier传递参数或传递多个键值对。 键值对与可以自动解释它们的日志数据分析器结合使用特别有用。

以下日志语句是等效的:

int newT = 15;
int oldT = 16;

// 使用经典API
logger.debug("oldT={} newT={} Temperature changed.", newT, oldT);

// 使用流式API
logger.atDebug().addKeyValue("oldT", oldT).addKeyValue("newT", newT).log("Temperature changed.");

API 的键值对变体将键值对存储为单独的对象。 org.slf4j.Logger 类中的默认实现将键值对作为消息的前缀。 日志后端是自由的,甚至鼓励提供更可定制的行为。

在部署时与日志框架绑定

如前所述,SLF4J 支持各种日志框架。 SLF4J 发行版附带了几个称为“SLF4J 绑定”的 jar 文件,每个绑定对应一个受支持的框架。

slf4j-log4j12-1.7.36.jar

log4j 1.2 版的绑定/提供程序,一个广泛使用的日志框架。 鉴于 log4j 1.x 已在 2015 年和 2022 年宣布 EOL,从 SLF4J 1.7.35 开始,slf4j-log4j 模块在构建时自动重定向到 slf4j-reload4j 模块。 假设您希望继续使用 log4j 1.x 框架,我们强烈建议您改用 slf4j-reload4j。 见下文。

slf4j-reload4j-1.7.36.jar

自 1.7.33 以来 reload4j 框架的绑定/提供程序。 Reload4j 是 log4j 版本 1.2.7 的直接替代品。 您还需要将 reload4j.jar 放在您的类路径上。

slf4j-jdk14-1.7.36.jar

java.util.logging 的绑定/提供程序,也称为 JDK 1.4 日志记录

slf4j-nop-1.7.36.jar

NOP 的绑定/提供程序,默默地丢弃所有日志记录。

slf4j-simple-1.7.36.jar

简单实现的绑定/提供程序,它将所有事件输出到 System.err。 只打印级别 INFO 和更高级别的消息。 此绑定在小型应用程序的上下文中可能很有用。

logback-classic-1.2.10.jar (需要 logback-core-1.2.10.jar)

原生实现 SLF4J 项目外部还有 SLF4J 绑定/提供程序,例如 原生实现 SLF4J 的 logback。 Logback 的 ch.qos.logback.classic.Logger 类是 SLF4J 的 org.slf4j.Logger 接口的直接实现。 因此,将 SLF4J 与 logback 结合使用涉及严格的零内存和计算开销。

要切换日志框架,只需替换类路径上的 slf4j 绑定。 例如,要从 java.util.logging 切换到 log4j,只需将 slf4j-jdk14-1.7.36.jar 替换为 slf4j-log4j12-1.7.36.jar。

SLF4J 不依赖任何特殊的类加载器机制。 事实上,每个 SLF4J 绑定在编译时都是硬连线的,以使用一个且只有一个特定的日志框架。 例如,slf4j-log4j12-1.7.36.jar 绑定在编译时绑定为使用 log4j。 在您的代码中,除了 slf4j-api-1.7.36.jar 之外,您只需将一个且只有一个您选择的绑定拖放到适当的类路径位置。 不要在类路径上放置多个绑定。

从 2.0.0 开始,从 2.0.0 版本开始,SLF4J 绑定被称为提供者。 尽管如此,总体思路还是一样的。 SLF4J API 版本 2.0.0 依赖 ServiceLoader 机制来查找其日志记录后端。 有关更多详细信息,请参阅相关的常见问题解答条目。

这是一般想法的图形说明。

SLF4J 接口及其各种适配器非常简单。 大多数熟悉 Java 语言的开发人员应该能够在不到一小时的时间内阅读并完全理解代码。 无需了解类加载器,因为 SLF4J 不使用也不直接访问任何类加载器。 因此,SLF4J 没有遇到使用 Jakarta Commons Logging (JCL) 观察到的类加载器问题或内存泄漏。

鉴于 SLF4J 接口及其部署模型的简单性,新日志框架的开发人员应该会发现编写 SLF4J 绑定非常容易。

类库

广泛分布的组件和库的作者可以针对 SLF4J 接口进行编码,以避免将日志框架强加给最终用户。 因此,最终用户可以在部署时通过在类路径上插入相应的 slf4j 绑定来选择所需的日志框架,稍后可以通过用类路径上的另一个绑定替换现有绑定并重新启动应用程序来更改该绑定。 这种方法已被证明是简单且非常健壮的。

从 SLF4J 版本 1.6.0 开始,如果在类路径上找不到绑定,则 slf4j-api 将默认为丢弃所有日志请求的无操作实现。 因此,SLF4J 1.6.0 及更高版本不会因为缺少 org.slf4j.impl.StaticLoggerBinder 类而引发 NoClassDefFoundError ,而是会发出一条关于没有绑定的警告消息,并继续丢弃所有日志请求而无需进一步抗议。 例如,让 Wombat 成为一些依赖 SLF4J 进行日志记录的生物学相关框架。 为了避免将日志框架强加给最终用户,Wombat 的发行版包含 slf4j-api.jar 但没有绑定。 即使类路径上没有任何 SLF4J 绑定,Wombat 的分发仍然可以开箱即用,并且不需要最终用户从 SLF4J 的网站下载绑定。 只有当最终用户决定启用日志记录时,她才需要安装与她选择的日志记录框架相对应的 SLF4J 绑定。

基本规则 嵌入式组件(例如库或框架)不应声明对任何 SLF4J 绑定/提供程序的依赖,而应仅依赖 slf4j-api。 当库声明对特定绑定的传递依赖时,该绑定被强加给最终用户,否定了 SLF4J 的目的。 请注意,声明对绑定的非传递依赖(例如用于测试)不会影响最终用户。

声明项目依赖项以进行日志记录

鉴于 Maven 的传递依赖规则,对于“常规”项目(不是库或框架),声明日志依赖关系可以通过单个依赖声明来完成。

LOGBACK-CLASSIC 如果您希望使用 logback-classic 作为底层日志框架,您需要做的就是在 pom.xml 文件中声明“ch.qos.logback:logback-classic”作为依赖项,如下所示。 除了 logback-classic-1.2.10.jar,这会将 slf4j-api-1.7.36.jar 和 logback-core-1.2.10.jar 拉入您的项目。 请注意,明确声明对 logback-core-1.2.10 或 slf4j-api-1.7.36.jar 的依赖并没有错,并且可能需要借助 Maven 的“最近定义”依赖调解规则来强制实施所述工件的正确版本

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

RELOAD4J 如果您希望使用 reload4j 作为底层日志框架,您需要做的就是在 pom.xml 文件中声明“org.slf4j:slf4j-reload4j”作为依赖项,如下所示。 除了 slf4j-reload4j-1.7.36.jar,这会将 slf4j-api-1.7.36.jar 和 reload4j-1.2.19.jar 拉入您的项目。 请注意,明确声明对 reload4j-1.2.19.jar 或 slf4j-api-1.7.36.jar 的依赖并没有错,并且可能需要借助 Maven 的“最近定义”依赖调解规则来强制实施所述工件的正确版本 .

<dependency> 
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-reload4j</artifactId>
  <version>1.7.36</version>
</dependency>

LOG4J 从 1.7.35 版开始,通过 Maven <relocation> 指令声明对 org.slf4j:slf4j-log4j12 的依赖重定向到 org.slf4j:slf4j-reload4j。

<dependency> 
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.7.36</version>
</dependency>

JAVA.UTIL.LOGGING 如果您希望使用 java.util.logging 作为底层日志记录框架,您需要做的就是在 pom.xml 文件中声明“org.slf4j:slf4j-jdk14”作为依赖项,如下所示 . 除了 slf4j-jdk14-1.7.36.jar,这会将 slf4j-api-1.7.36.jar 拉入您的项目。 请注意,明确声明对 slf4j-api-1.7.36.jar 的依赖并没有错,并且可能需要借助 Maven 的“最近定义”依赖调解规则来强制实施所述工件的正确版本。

<dependency> 
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-jdk14</artifactId>
  <version>1.7.36</version>
</dependency>

二进制兼容性

SLF4J 绑定指定诸如 slf4j-jdk14.jar 或 slf4j-log4j12.jar 之类的工件,用于将 slf4j 绑定到底层日志框架,例如 java.util.logging 和 log4j。

混合不同版本的 slf4j-api.jar 和 SLF4J 绑定可能会导致问题。 例如,如果您使用的是 slf4j-api-1.7.36.jar,那么您也应该使用 slf4j-simple-1.7.36.jar,使用 slf4j-simple-1.5.5.jar 将不起作用。

但是,从客户端的角度来看,所有版本的 slf4j-api 都是兼容的。 使用 slf4j-api-N.jar 编译的客户端代码可以在任何 N 和 M 的 slf4j-api-M.jar 下完美运行。您只需确保绑定的版本与 slf4j-api.jar 的版本匹配。 您不必担心项目中给定依赖项使用的 slf4j-api.jar 版本。 您始终可以使用任何版本的 slf4j-api.jar,只要 slf4j-api.jar 的版本及其绑定匹配,就可以了。

在初始化时,如果 SLF4J 怀疑可能存在 slf4j-api 与绑定版本不匹配的问题,它会发出疑似不匹配的警告。

通过 SLF4J 合并日志记录

很多时候,一个给定的项目将依赖于依赖于除 SLF4J 之外的日志 API 的各种组件。 根据 JCL、java.util.logging、log4j 和 SLF4J 的组合来查找项目是很常见的。 然后希望通过单个通道合并日志记录。 SLF4J 通过为 JCL、java.util.logging 和 log4j 提供桥接模块来满足这个常见的用例。 有关更多详细信息,请参阅桥接旧版 API 页面。

支持 JDK 平台日志记录 (JEP 264) SLF4J

自 2.0.0-ALPHA5 起 slf4j-jdk-platform-logging 模块增加了对 JDK 平台日志记录的支持。

<dependency> 
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-jdk-platform-logging</artifactId>
  <version>2.0.0-alpha7</version>
</dependency>

映射诊断上下文 (MDC) 支持

“映射诊断上下文”本质上是由日志框架维护的映射,其中应用程序代码提供键值对,然后可以由日志框架插入日志消息中。 MDC 数据在过滤消息或触发某些操作方面也非常有用。

SLF4J 支持 MDC 或映射诊断上下文。 如果底层日志框架提供 MDC 功能,那么 SLF4J 将委托给底层框架的 MDC。 请注意,目前只有 log4j 和 logback 提供 MDC 功能。 如果底层框架不提供 MDC,例如 java.util.logging,则 SLF4J 仍将存储 MDC 数据,但其中的信息需要通过自定义用户代码检索。

因此,作为 SLF4J 用户,您可以在存在 log4j 或 logback 的情况下利用 MDC 信息,但不会将这些日志框架作为依赖项强加给您的用户。

有关 MDC 的更多信息,请参阅 logback 手册中有关 MDC 的章节。

执行摘要

优势

描述

在部署时选择您的日志框架

通过在类路径中插入适当的 jar 文件(绑定),可以在部署时插入所需的日志框架。

快速故障操作

由于 JVM 加载类的方式,框架绑定将在很早的时候自动验证。 如果 SLF4J 在类路径上找不到绑定,它将发出一条警告消息并默认为无操作实现。

流行日志框架的绑定

SLF4J 支持流行的日志框架,即 log4j、java.util.logging、Simple logging 和 NOP。 logback 项目原生支持 SLF4J。

桥接旧的日志记录 API

JCL over SLF4J 的实现,即 jcl-over-slf4j.jar,将允许您的项目逐步迁移到 SLF4J,而不会破坏与使用 JCL 的现有软件的兼容性。 同样,log4j-over-slf4j.jar 和 jul-to-slf4j 模块将允许您将 log4j 和 java.util.logging 调用分别重定向到 SLF4J。 有关更多详细信息,请参阅桥接旧版 API 页面。

迁移您的源代码

slf4j-migrator 实用程序可以帮助您迁移源代码以使用 SLF4J。

支持参数化日志消息

所有 SLF4J 绑定都支持参数化日志消息,性能结果显著提高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值