SLF4J简介与使用(整合log4j)

2023-11-07

一、概念

SLF4J的全称是Simple Logging Facade for Java,即简单日志门面。SLF4J并不是具体的日志框架,而是作为一个简单门面服务于各类日志框架,如java.util.logging, logback和log4j。

SLF4J提供了统一的记录日志的接口,对不同日志系统的具体实现进行了抽象化,只要按照其提供的方法记录即可,最终日志的格式、记录级别、输出方式等通过绑定具体的日志系统来实现。

使用SLF4J的好处在于,你只需要按统一的方式写记录日志的代码,如:

public class LoggerTest {
    private static final Logger logger = LoggerFactory.getLogger(Tester.class);
    public static void main(String[] args) {
        logger.info("Current Time: {}", System.currentTimeMillis());
    }
}

SLF4J支持{}作为占位符,等价于C语言中的%s,而不必再进行字符串的拼接,效率有显著的提升(见后面运行结果)。

而无需关心日志是通过哪个日志系统,以什么风格输出的。因为它们取决于部署项目时绑定的日志系统。
例如,在项目中使用了SLF4J记录日志,并且绑定了log4j,则日志会以log4j的风格输出;后期需要改为以logback的风格输出日志,只需要将log4j替换成logback即可,不用修改项目中的代码。

二、依赖

SLF4J绑定各类日志框架的原理图:

concrete-bindings.png

由上图可知,使用SLF4J依赖于slf4j-api-1.8.0-alpha2.jar,部署时还依赖于要绑定的日志系统的jar包和相应的适配器jar包。

以绑定log4j为例,需要导入以下包:

  • slf4j-api-1.8.0-alpha2.jar
  • log4j-1.2.17.jar
  • slf4j-log4j12-1.8.0-alpha2.jar

如果使用Maven,则只需添加适配器jar包依赖即可:

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

三、使用示例

这里以SLF4J + log4j为例。

1.在pom.xml中添加依赖(或者手动导入上述3个jar包):

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

2.配置log4j

在类路径下创建log4j.properties配置文件,这样log4j会自动加载配置文件。

# rootLogger参数分别为:根Logger级别,输出器stdout,输出器log
log4j.rootLogger = info,stdout,log

# 输出信息到控制台
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d [%-5p] %l %rms: %m%n

# 输出DEBUG级别以上的日志到D://logs/debug.log
log4j.appender.log = org.apache.log4j.DailyRollingFileAppender
log4j.appender.log.DatePattern = '.'yyyy-MM-dd
log4j.appender.log.File = D://debug.log
log4j.appender.log.Encoding = UTF-8
#log4j.appender.log.Threshold = INFO
log4j.appender.log.layout = org.apache.log4j.PatternLayout
log4j.appender.log.layout.ConversionPattern = %d [%-5p] (%c.%t): %m%n

将log4j.properties放在类路径下是最简单的做法,当然也可以通过PropertyConfigurator在代码中加载或者通过web.xml加载。

3.测试代码

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggerTest {
    private static final Logger logger = LoggerFactory.getLogger(LoggerTest.class);
    public static void main(String[] args) {
        logger.info("Current Time: {}", System.currentTimeMillis());
        logger.info("Current Time: " + System.currentTimeMillis());
        logger.info("Current Time: {}", System.currentTimeMillis());
        logger.trace("trace log");
        logger.warn("warn log");
        logger.debug("debug log");
        logger.info("info log");
        logger.error("error log");
    }
}

4.运行结果

2017-06-16 23:11:05,490 [INFO ] com.jiapengcs.demos.slf4j.LoggerTest.main(LoggerTest.java:14) 0ms: Current Time: 1497625865488
2017-06-16 23:11:05,493 [INFO ] com.jiapengcs.demos.slf4j.LoggerTest.main(LoggerTest.java:15) 3ms: Current Time: 1497625865493
2017-06-16 23:11:05,493 [INFO ] com.jiapengcs.demos.slf4j.LoggerTest.main(LoggerTest.java:16) 3ms: Current Time: 1497625865493
2017-06-16 23:11:05,495 [WARN ] com.jiapengcs.demos.slf4j.LoggerTest.main(LoggerTest.java:18) 5ms: warn log
2017-06-16 23:11:05,495 [INFO ] com.jiapengcs.demos.slf4j.LoggerTest.main(LoggerTest.java:20) 5ms: info log
2017-06-16 23:11:05,495 [ERROR] com.jiapengcs.demos.slf4j.LoggerTest.main(LoggerTest.java:21) 5ms: error log

通常输出日志开销非常大,从上述结果可见,SLF4J通过{}作为占位符的方式输出字符串,相比字符串拼接的方式,效率有显著的提升。

5.更换日志系统

看到这里,你可能会有疑问:既然都用了log4j,为什么还要用SLF4J来写记录日志的代码呢,不是多此一举吗?

答案是否定的。假设我们不再需要log4j,而是希望改为使用java自带logging记录日志,我们需要做的仅仅是将pom.xml的依赖项slf4j-log4j12改为slf4j-jdk14即可,无需对上述测试代码做任何修改。

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

是的,就是这么简单。再次运行测试代码:

六月 16, 2017 10:32:30 下午 com.jiapengcs.demos.slf4j.LoggerTest main
信息: Current Time: 1497623550843
六月 16, 2017 10:32:30 下午 com.jiapengcs.demos.slf4j.LoggerTest main
信息: Current Time: 1497623550874
六月 16, 2017 10:32:30 下午 com.jiapengcs.demos.slf4j.LoggerTest main
信息: Current Time: 1497623550875
六月 16, 2017 10:32:30 下午 com.jiapengcs.demos.slf4j.LoggerTest main
警告: warn log
六月 16, 2017 10:32:30 下午 com.jiapengcs.demos.slf4j.LoggerTest main
信息: info log
六月 16, 2017 10:32:30 下午 com.jiapengcs.demos.slf4j.LoggerTest main
严重: error log

我们发现,此时日志已经变为以logging的方式输出。

四、总结

SLF4J的使用非常简单,甚至连官网上都说鉴于它太轻量,文档篇幅不长。

Given the small size of SLF4J, its documentation is not very lengthy.

在《阿里巴巴Java开发手册(正式版)》中,日志规约一项第一条就强制要求使用SLF4J:

1.【强制】应用中不可直接使用日志系统(Log4j、Logback)中的API,而应依赖使用日志框架SLF4J中的API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

所以从现在开始使用SLF4J吧!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SLF4J简介与使用(整合log4j) 的相关文章

随机推荐

  • 高数【连续、间断点】--猴博士爱讲课

    第二课 连续 间断点 函数连续不连续是要看区间的 1 3 证明f x 在某点连续 例一 试证明 f x
  • 蓝桥杯真题31日冲刺国一

    大家好 我是泡泡 接下来几天每天都有复习 目录 今日练习专题 一丶成绩统计 二丶既约分数 三丶最优包含 复习专题 一丶空间 二丶等差数列 三丶回文日期 四丶青蛙跳杯子 今日练习专题 一丶成绩统计 题目链接 成绩统计 蓝桥云课 lanqiao
  • 机器学习中如何选择分类器

    在机器学习中 分类器作用是在标记好类别的训练数据基础上判断一个新的观察样本所属的类别 分类器依据学习的方式可以分为非监督学习和监督学习 非监督学习顾名思义指的是给予分类器学习的样本但没有相对应类别标签 主要是寻找未标记数据中的隐藏结构 监督
  • C#实现的根据年月日计算星期几的函数

    算法如下 基姆拉尔森计算公式 W d 2 m 3 m 1 5 y y 4 y 100 y 400 mod 7 在公式中d表示日期中的日数 m表示月份数 y表示年数 注意 在公式中有个与其他公式不同的地方 把一月和二月看成是上一年的十三月和十
  • pandas 报警告:A value is trying to be set on a copy of a slice from a DataFrame

    pandas 报警告 A value is trying to be set on a copy of a slice from a DataFrame 我在抽取了原来DataFrame数据的几列后 对抽取后的数据进行赋值操作时弹出这个警告
  • 提取分割单引号 ‘ ‘ 之间的内容且不重复分割单引号 python

    分割两个单引号之间的内容 且不重复分割已使用的单引号 废话少说 直接上干货 import re result re findall string 将string替换为你需要分割的部分 示例代码 string jmp qword ptr ri
  • MySQL - Left Join和Inner Join的效率对比,以及优化

    最近在写代码的时候 遇到了需要多表连接的一个问题 初始sql类似于 select from a left join b on a id b aid left join c on c bid b id left join d on d cid
  • 什么是DI

    Spring致力于简化java企业级开发 促进代码松耦合 成功的关键在于依赖注入和AOP Spring通过应用上下文 Application Context 装载bean的定义并把他们组装起来 Spring应用上下文全权负责对象的创建和组装
  • python3发送邮件带附件,Python3.4 邮件发送(含带中文附件)详解

    import smtplib import os from email mime text import MIMEText from email mime multipart import MIMEMultipart from email
  • Xshell使用密钥登录Linux服务器

    1 使用如下命令生成密钥对 root xuegod130 ssh keygen Generating public private rsa key pair Enter file in which to save the key root
  • jsonp 实现跨域 同时也是一个 webflux 的demo 示例

    文章目录 核心原理 代码 html 服务端 java 为例子 服务端目录结构 核心原理 前端 使用js 创建 script 标签 将请求地址 放到其src 中 并将 script 标签追加到文档流 后端 根据约定好的 callback 字段
  • element-ui 首页布局

    效果 代码
  • [python]numpy 中的@运算

    运算其实等价于矩阵乘法 r location s y l location r location 1 np dot s y l location 与上面式子等价
  • java 保留字符串数字的位数,不够前面补0

    Test public void test this printToConsole autoGenericCode 10011 this printToConsole autoGenericCode 000 3 不够位数的在前面补0 保留c
  • 数模笔记——论文写作

    论文写作 各模块写作要点 数学建模论文的重要性 数学建模论文的写作是数学建模中重要的一个环节 数学建模的论文是参赛队工作的全面总结 也是评委评价建模成绩的主要依据 一篇好的论文应该逻辑清晰 在语言表述上清楚 数学符号标记清晰 对于读者或者评
  • 学习JavaScript以及React技术报告

    在学习JS中遇到的一些问题总结 1 我们需要在页面加载时能够通过javascript去动态操作html中的一些对象 对于这些操作 我们最好是在body中定义onload操作 然后在该操作中去完成这些任务 尽量避免在html中嵌入script
  • 操作系统课程设计3_系统调用

    一 实验目的 1 学习怎样重新编译 Linux 内核 2 理解 掌握 Linux 标准内核和发行版本内核的区别 二 实验内容 1 通过重新编译Linux来实现系统调用 2 通过增加模块来实现系统调用 三 实验步骤和结果 一 通过重新编译内核
  • Voting【Codeforces 1251 E1 && E2】【贪心】

    Educational Codeforces Round 75 Rated for Div 2 E2 Now elections are held in Berland and you want to win them More preci
  • Huawei Cloud EulerOS(Linux)常用命令汇总

    更改主机名称 hostnamectl set hostname
  • SLF4J简介与使用(整合log4j)

    一 概念 SLF4J的全称是Simple Logging Facade for Java 即简单日志门面 SLF4J并不是具体的日志框架 而是作为一个简单门面服务于各类日志框架 如java util logging logback和log4