SLF4J简介与使用(整合log4j)

SLF4J简介与使用(整合log4j)

一、概念

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绑定各类日志框架的原理图:

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

由上图可知,使用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包依赖即可

三、使用示例

这里以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.运行结果

2018-09-01 23:14:32,690 [INFO ] com.lun.helloslf4j.LoggerTest.main(LoggerTest.java:11) 2ms: Current Time: 1535814872683
2018-09-01 23:14:32,700 [INFO ] com.lun.helloslf4j.LoggerTest.main(LoggerTest.java:12) 12ms: Current Time: 1535814872700
2018-09-01 23:14:32,701 [INFO ] com.lun.helloslf4j.LoggerTest.main(LoggerTest.java:13) 13ms: Current Time: 1535814872701
2018-09-01 23:14:32,701 [WARN ] com.lun.helloslf4j.LoggerTest.main(LoggerTest.java:15) 13ms: warn log
2018-09-01 23:14:32,701 [INFO ] com.lun.helloslf4j.LoggerTest.main(LoggerTest.java:17) 13ms: info log
2018-09-01 23:14:32,701 [ERROR] com.lun.helloslf4j.LoggerTest.main(LoggerTest.java:18) 13ms: 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>

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

九月 01, 2018 11:25:35 下午 com.lun.helloslf4j.LoggerTest main
信息: Current Time: 1535815535309
九月 01, 2018 11:25:35 下午 com.lun.helloslf4j.LoggerTest main
信息: Current Time: 1535815535475
九月 01, 2018 11:25:35 下午 com.lun.helloslf4j.LoggerTest main
信息: Current Time: 1535815535477
九月 01, 2018 11:25:35 下午 com.lun.helloslf4j.LoggerTest main
警告: warn log
九月 01, 2018 11:25:35 下午 com.lun.helloslf4j.LoggerTest main
信息: info log
九月 01, 2018 11:25:35 下午 com.lun.helloslf4j.LoggerTest main
严重: error log

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

四、总结

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

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

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

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

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

引用

来源处

官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445990.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

multism中ui和uo应该怎么表示_王者荣耀:梦泪直播时谈到体验服大改动,表示装备的改动很关键...

王者荣耀的主播梦泪&#xff0c;大家都很熟了&#xff0c;也是一个很强的主播&#xff0c;他对于王者荣耀的理解&#xff0c;还是非常深刻的&#xff0c;而最近王者荣耀的体验服&#xff0c;进行了大改动&#xff0c;也是改变了很多的东西。对此&#xff0c;网友们也是非常的在…

FFmpeg源代码简单分析-通用-结构体分析-AVStream

参考链接 FFMPEG结构体分析&#xff1a;AVStream_雷霄骅的博客-CSDN博客_avstream AVStream AVStream是是存储每一个视频/音频流信息的结构体结构体的定义位于avformat.h重要参数介绍 int index&#xff1a;标识该视频/音频流AVCodecContext *codec&#xff1a;指向该视频/音…

在Windows下安装JDK的通常步骤

获取安装包 从官网或其他途径下载JDK的Windows版本的安装包&#xff0c;并点击安装。安装向导中无需选择配置项&#xff0c;默认操作即可&#xff0c;除了自定义的JDK安装目录。假设JDK的安装目录为C:\Program Files\Java。 设置环境变量 右击桌面上的计算机&#xff0c;在菜单…

怎么关闭或者卸载ivanti_电脑软件卸载不了怎么办,教您解决电脑软件无法卸载方法技巧...

我们在使用电脑的过程中&#xff0c;肯定会安装各种软件&#xff0c;但是一些软件在使用完之后就不会再使用了&#xff0c;但又无法卸载。下面由小编分享一下电脑安装的软件无法卸载解决方法&#xff0c;如果你在某卸载软件的时候出现无法卸载的情况&#xff0c;不妨通过以下方…

FFmpeg源代码简单分析-通用-结构体分析-AVPacket

参考链接 FFMPEG结构体分析&#xff1a;AVPacket_雷霄骅的博客-CSDN博客_avpacket AVPacket AVPacket是存储压缩编码数据相关信息的结构体结构体的定义位于packet.h重要参数介绍 uint8_t *data&#xff1a;压缩编码的数据。例如对于H.264来说。1个AVPacket的data通常对应一个…

h5支付不能打开支付宝 ios_iOS WKWebview中无法调起支付宝/微信客户端支付问题的解决方法...

这两个的解决思路都是要在下面这个方法中先拦截相应的url&#xff0c;再单独处理- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;支付宝…

解决Github图片加载失败

问题描述 浏览自己Github某仓库的README.md内时&#xff0c;发现文档的图片始终加载不出&#xff0c;打开浏览器后台&#xff0c;冒出一片红&#xff0c;Failed to load resource: net::ERR_CONNECTION_RESET&#xff0c;如下图所示&#xff1a; 问题分析 可能造成这问题的原…

FFmpeg源代码简单分析-通用-结构体分析-AVFrame

参考链接 FFMPEG结构体分析&#xff1a;AVFrame_雷霄骅的博客-CSDN博客 AVFrame AVFrame是包含码流参数较多的结构体结构体的定义位于frame.hAVFrame结构体一般用于存储原始数据&#xff08;即非压缩数据&#xff0c;例如对视频来说是YUV&#xff0c;RGB&#xff0c;对音频来…

python 求子字符串_(6)KMP算法(求子串的位置)______字符串的匹配

问题&#xff1a;已知字符串 B 是字符串 A 的一个子串,问字符串 B 在字符串 A 的第一次出现位置.暴力方法:从 A 字符串 的每个位置开始对字符串 B 进行匹配. 这种方法根据数据的不同 复杂度不同最高可以达到O( m*n ). (m,n分别为两个字符串的长度)KMP算法&#xff1a;我们先来看…

用Python将多张图片合并成一PDF文件

先前条件 需要安装两模块&#xff1a;fpdf、PIL pip install fpdfpip install PIL 放码过来 from fpdf import FPDF from PIL import Image import osdef makePdf(pdfFileName, listPages):cover Image.open(listPages[0])width, height cover.sizepdf FPDF(unit "…

FFmpeg源代码简单分析-通用-结构体分析-关键结构体之间的关系

参考链接 FFMPEG中最关键的结构体之间的关系_雷霄骅的博客-CSDN博客_ffmpeg 结构体关系 最关键的结构体可以分成以下几类&#xff1a; 解协议&#xff08;http,rtsp,rtmp,mms&#xff09; AVIOContext&#xff0c;URLProtocol&#xff0c;URLContext主要存储视音频使用的协…

用Python下载文件

前提条件 需要事先安装requests模块&#xff1a; pip install requests 放码过来 import requestsurl XXX #文件下载来源URL filename #下载到本地后新文件名 r requests.get(url) with open(filename, "wb") as code:code.write(r.content)实战演习 从目标…

distenct oracle_Oracle的distinct关键字

distinct关键字用于从查询的结果集中筛选出唯一值的记录。我们通过示例来介绍distinct关键字的用法。一、生成测试数据用以下SQL创建超女基本信息表(T_GIRL)&#xff0c;插入一些测试数据。create table T_GIRL(id char(4) not null, -- 编号name varchar2(30) not null, -- 姓…

FFmpeg源代码简单分析-通用-常见结构体的初始化和销毁(AVFormatContext,AVFrame等)

参考链接 FFmpeg源代码简单分析&#xff1a;常见结构体的初始化和销毁&#xff08;AVFormatContext&#xff0c;AVFrame等&#xff09;_雷霄骅的博客-CSDN博客 结构体 AVFormatContext&#xff1a;统领全局的基本结构体。主要用于处理封装格式&#xff08;FLV/MKV/RMVB等&…

python中object转为float_object格式怎样无损转换成float64格式

这次给大家带来object格式怎样无损转换成float64格式&#xff0c;object格式无损转换成float64格式的注意事项有哪些&#xff0c;下面就是实战案例&#xff0c;一起来看一下。在数据处理过程中比如从CSV文件中导入数据data_df pd.read_csv("names.csv")在处理之前一…

FFmpeg源代码简单分析-通用-avio_open2()

参考链接 FFmpeg源代码简单分析&#xff1a;avio_open2()_雷霄骅的博客-CSDN博客_avio_open avio_open2() 该函数用于打开FFmpeg的输入输出文件avio_open2()的声明位于libavformat\avio.h文件中&#xff0c;如下所示。 /*** Create and initialize a AVIOContext for accessi…

用Tomcat构建一个简单图片服务器

前提条件 Tomcat 7.0.90 方法一&#xff1a;修改配置文件 在TOMCAT_HOME/conf/server.xml配置文件内的<Host>内添加一子标签&#xff1a; <Context docBase"C:\exambase\" path"/img"/>方法二&#xff1a;添加Servlet 新建一应用&#xf…

flash静态的农夫走路_健身神动作——你不知道的“农夫行走”

原标题&#xff1a;健身神动作——你不知道的“农夫行走”本期导读握力是训练中及其重要的一环&#xff0c;强大的握力会使你的训练效果MAX&#xff0c;就像开了加速器一样&#xff01;很多人把握力和前臂力量混为一谈&#xff0c;主要使用腕弯举提高握力。实际上&#xff0c;握…

FFmpeg源代码简单分析-通用-av_find_decoder()和av_find_encoder()

参考链接 FFmpeg源代码简单分析&#xff1a;av_find_decoder()和av_find_encoder()_雷霄骅的博客-CSDN博客_avcodec_find_encoder avcodec_find_encoder avcodec_find_encoder()用于查找FFmpeg的编码器avcodec_find_encoder()的声明位于libavcodec\codec.h 版本差异avcode…

用Java的Set实现交并差等集合运算

放码过来 package com.lun.util;import java.util.HashSet; import java.util.Set;public class SetUtils {public static <T> Set<T> union(Set<T> setA, Set<T> setB) {Set<T> tmp new HashSet<T>(setA);tmp.addAll(setB);return tmp;…