SLF4J用户手册
Simple Logging Facade for Java(SLF4J)用作各种日志框架的简单外观或抽象,例如java.util.logging,logback和log4j。SLF4J允许最终用户在部署时插入所需的日志记录框架。请注意,启用SLF4J的库/应用程序意味着只添加一个强制依赖项,即 slf4j-api-1.8.0-beta2.jar。
从1.6.0开始如果在类路径上没有找到绑定,则SLF4J将默认为无操作实现。
从1.7.0开始,Logger
界面中的打印方法 现在提供了接受varargs 而不是varargs的变体Object[]
。此更改意味着SLF4J需要JDK 1.5或更高版本。在Java下,Java编译器将方法中的varargs部分转换为 Object[]
。因此,编译器生成的Logger接口在1.7.x中与1.6.x版本无法区分。因此,SLF4J版本1.7.x与SLF4J版本1.6.x完全100%无错或兼容。
自1.7.5记录器检索时间显着改善。考虑到改进的程度,强烈建议用户迁移到SLF4J 1.7.5或更高版本。
从1.7.9开始,通过将slf4j.detectLoggerNameMismatch
系统属性设置 为true,SLF4J可以自动发现错误命名的记录器。
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.8.0-beta2.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.8.0-beta2.jar,以便您的类路径包含:
- SLF4J-API-1.8.0-beta2.jar
- SLF4J-simple-1.8.0-beta2.jar
编译和运行HelloWorld现在将在控制台上产生以下输出。
0 [main] INFO HelloWorld - Hello World
典型使用模式
下面的示例代码说明了SLF4J的典型使用模式。请注意在第15行使用{} -placeholders。请参阅问题“最快的记录方式是什么?” 在常见问题中了解更多详情。
1: import org.slf4j.Logger;
2: import org.slf4j.LoggerFactory;
3:
4: public class Wombat {
5:
6: final Logger logger = LoggerFactory.getLogger(Wombat.class);
7: Integer t;
8: Integer oldT;
9:
10: public void setTemperature(Integer temperature) {
11:
12: oldT = t;
13: t = temperature;
14:
15: logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);
16:
17: if(temperature.intValue() > 50) {
18: logger.info("Temperature has risen above 50 degrees.");
19: }
20: }
21: }
在部署时与日志记录框架绑定
如前所述,SLF4J支持各种日志框架。SLF4J发行版附带了几个称为“SLF4J绑定”的jar文件,每个绑定对应一个受支持的框架。
-
SLF4J-log4j12-1.8.0-beta2.jar
绑定log4j 1.2版,一个广泛使用的日志框架。您还需要将log4j.jar放在类路径上。
-
SLF4J-jdk14-1.8.0-beta2.jar
绑定java.util.logging,也称为JDK1.4日志记录
-
SLF4J-NOP-1.8.0-beta2.jar
绑定NOP,静默丢弃所有日志记录。
-
SLF4J-简单1.8.0-beta2.jar
绑定简单 实现,将所有事件输出到System.err。仅打印INFO级别以上的消息。此绑定在小应用程序的上下文中可能很有用。
-
SLF4J-JCL-1.8.0-beta2.jar
绑定Jakarta Commons Logging。此绑定将委派所有SLF4J日志记录到JCL。
-
logback-classic-1.0.13.jar(需要logback-core-1.0.13.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.8.0-beta2.jar替换为slf4j-log4j12-1.8.0-beta2.jar即可。
SLF4J不依赖于任何特殊的类装载机械。实际上,每个SLF4J绑定在编译时都是硬连线的, 以使用一个且只有一个特定的日志记录框架。例如,slf4j-log4j12-1.8.0-beta2.jar绑定在编译时绑定以使用log4j。在您的代码中,除了slf4j-api-1.8.0-beta2.jar之外,您只需将 您选择的一个且只有一个绑定放到相应的类路径位置。不要在类路径上放置多个绑定。以下是一般概念的图解说明。
SLF4J接口及其各种适配器非常简单。熟悉Java语言的大多数开发人员应该能够在不到一小时的时间内阅读并完全理解代码。不需要类加载器的知识,因为SLF4J不能使用,也不能直接访问任何类加载器。因此,SLF4J不会遇到使用Jakarta Commons Logging(JCL)观察到的类加载器问题或内存泄漏。
鉴于SLF4J接口及其部署模型的简单性,新的日志框架的开发人员应该发现编写SLF4J绑定非常容易。
Libraries
广泛分布的组件和库的作者可以针对SLF4J接口进行编码,以避免在其最终用户上强加日志框架。因此,最终用户可以通过在类路径上插入相应的slf4j绑定来在部署时选择所需的日志框架,稍后可以通过在类路径上替换现有绑定并重新启动应用程序来更改。事实证明,这种方法简单而且非常稳健。
从SLF4J版本1.6.0开始,如果在类路径上找不到绑定,则slf4j-api将默认为无操作实现,丢弃所有日志请求。因此,SLF4J版本1.6.0及更高版本将发出一条关于缺少绑定的警告消息,并继续丢弃所有日志请求而不进一步抗议,而不是NoClassDefFoundError
因为 org.slf4j.impl.StaticLoggerBinder
缺少类而抛出a 。例如,让Wombat成为一些与生物学相关的框架,具体取决于SLF4J的日志记录。为了避免在最终用户上强加日志框架,Wombat的发行版包括slf4j-api.jar 但没有约束力。即使在类路径上没有任何SLF4J绑定,Wombat的发行版仍然可以开箱即用,而且不需要最终用户从SLF4J的网站下载绑定。只有当最终用户决定启用日志记录时,才需要安装与她选择的日志框架相对应的SLF4J绑定。
基本规则 嵌入式组件(如库或框架)不应声明对任何SLF4J绑定的依赖性,而只依赖于slf4j-api。当库声明对特定绑定的传递依赖时,该绑定强加给最终用户否定SLF4J的目的。请注意,声明对绑定的非传递依赖性(例如,用于测试)不会影响最终用户。
嵌入式组件中的SLF4J用法也在FAQ中讨论,与日志记录配置,依赖性减少和 测试有关。
声明日志记录的项目依赖项
鉴于Maven的传递依赖规则,对于“常规”项目(不是库或框架),可以使用单个依赖性声明来声明日志记录依赖性。
LOGBACK-CLASSIC
如果您希望使用logback-classic作为底层日志记录框架,那么您需要做的就是将“ch.qos.logback:logback-classic”声明为pom.xml文件中的依赖项,如下所示。除了logback-classic-1.0.13.jar之外,这还会将slf4j-api-1.8.0-beta2.jar以及logback-core-1.0.13.jar引入到您的项目中。请注意,明确声明对 logback-core-1.0.13或slf4j-api-1.8.0-beta2.jar的依赖是没有错的,并且可能需要凭借Maven的“最接近定义”依赖关系强加所述工件的正确版本调解规则。
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
LOG4J
如果您希望使用log4j作为底层日志记录框架,您需要做的就是将“org.slf4j:slf4j-log4j12”声明为pom.xml文件中的依赖项, 如下所示。除了 slf4j-log4j12-1.8.0-beta2.jar之外,这还会将 slf4j-api-1.8.0-beta2.jar以及 log4j-1.2.17.jar导入到您的项目中。请注意,明确声明对 log4j-1.2.17.jar或 slf4j-api-1.8.0-beta2.jar的依赖是没有错的,并且可能需要凭借Maven的“最接近定义”依赖关系强加所述工件的正确版本调解规则。
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.8.0-beta2</version>
</dependency>
JAVA.UTIL.LOGGING
如果你想使用java.util.logging作为底层日志框架,你需要做的就是在你的pom.xml 文件中声明“org.slf4j:slf4j-jdk14”作为依赖项,如下所示。除了slf4j-jdk14-1.8.0-beta2.jar之外,这将把 slf4j-api-1.8.0-beta2.jar引入你的项目。请注意,明确声明对 slf4j-api-1.8.0-beta2.jar的依赖是没有错的,并且可能需要凭借Maven的“最接近定义”依赖关系中介规则强加所述工件的正确版本。
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.8.0-beta2</version>
</dependency>
兼容性
SLF4J绑定指定一个工件,例如 slf4j-jdk14.jar或slf4j-log4j12.jar,用于 将 slf4j 绑定到底层日志框架,例如java.util.logging和log4j。
从客户的角度来看,所有版本的slf4j-api都是兼容的。对于任何N和M,使用slf4j-api-N.jar编译的客户端代码将与slf4j-api-M.jar完全匹配。您只需要确保绑定的版本与slf4j-api.jar的版本匹配。您不必担心项目中给定依赖项使用的slf4j-api.jar版本。
混合不同版本的slf4j-api.jar和SLF4J绑定可能会导致问题。例如,如果您使用的是slf4j-api-1.8.0-beta2.jar,那么您还应该使用slf4j-simple-1.8.0-beta2.jar,使用slf4j-simple-1.5.5.jar将无效。
但是,从客户端的角度来看,所有版本的slf4j-api都是兼容的。对于任何N和M,使用slf4j-api-N.jar编译的客户端代码将与 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的页面。
映射诊断上下文(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 | 通过SLF4J实现JCL,即 jcl-over-slf4j.jar,将允许您的项目逐步迁移到SLF4J,而不会破坏与使用JCL的现有软件的兼容性。类似地,log4j-over-slf4j.jar和jul-to-slf4j模块将允许您将log4j和java.util.logging调用重定向到SLF4J。有关更多详细信息,请参阅桥接旧API的页面。 |
迁移您的源代码 | 该SLF4J-迁移工具可以帮助您迁移源使用SLF4J。 |
支持参数化日志消息 | 所有SLF4J绑定都支持参数化日志消息,并显着提高了性能 结果。 |