log4j 和slf4j的比较
log4j 和slf4j的比较#
slf4j
官网:https://www.slf4j.org/manual.html
slf4j(simple logging facade for java)是Java的简单的日志门面,它不是具体的日志解决方案,它只服务于各种各样slf4j-logo的日志系统。这里的slf4j-logo可以是log4j,可以是jdk的日志,可以是logback,还可以是slf4j-simple等等。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。这里其实用到了一种设计模式(Facade设计模式,门面设计模式)。如下图:

使用方式:
在系统开发中,统一按照slf4j的API进行开发,在部署时,选择不同的日志系统包,即可自动转换到不同的日志系统上。比如:选择JDK自带的日志系统,则只需要将slf4j-api-1.5.10.jar和slf4j-jdk14-1.5.10.jar放置到classpath中即可,如果中途无法忍受JDK自带的日志系统了,想换成log4j的日志系统,仅需要用slf4j-log4j12-1.5.10.jar替换slf4j-jdk14-1.5.10.jar即可(当然也需要log4j的jar及配置文件)
比如:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Slf4jTest {
// 首先获得日志记录这个对象
private static final Logger logger = LoggerFactory.getLogger(Slf4jTest.class);
public static void main(String[] args) {
// 记录error信息
logger.error("[info message]");
// 记录info,还可以传入参数
logger.info("[info message]{},{},{},{}", "abc", false, 123, new Slf4jTest());
// 记录deubg信息
logger.debug("[debug message]");
// 记录trace信息
logger.trace("[trace message]");
System.out.println("hello world");
}
}
原理介绍--静态绑定
大家看到要使用哪种日志系统,只需要将对应的日志系统所需要的jar包文件(包括slf4j提供的jar包和日志系统自身依赖的jar包,例如:slf4j-log4j12-1.5.10.jar和log4j.1.2.jar)放入classpath即可,slf4j可以自动探测具体使用哪种日志系统,这种技术被称为静态绑定。
在实际使用中,我们通过LoggerFactory.getLogger()获得logger,查看LoggerFactory的源代码会发现如下两点,
LoggerFactory通过StaticLoggerBinder.getSingleton().getLoggerFactory()获得LogFactory,然后再通过该LogFactory来获取logger的
但是StaticLoggerBinder类并不在slf4j-api-1.5.10.jar中,分析与具体日志系统相关的jar包,会发现每个jar包都有一个StaticLoggerBinder类的实现(如slf4j-log4j12-1.5.10.jar、slf4j-simple-1.5.10.jar、slf4j-jdk14-1.5.10.jar均有StaticLoggerBinder类实现),这就很明白了,slf4j在启动时会动态到classpath中查找StaticLoggerBinder类,找到之后就可以生成对应日志系统的日志文件了。
这里就有一个问题了,slf4j是如何将自己的通用日志格式转成不同的日志系统的格式的呢?
不同日志系统包都会有一个Adapter,用来在slf4j和不同日志系统之间做转换。
我们如果使用Springboot初始化项目,那么spring-boot-starter-web中包含了slf4j的依赖,直接用就行了
log4j
官网:https://logging.apache.org/log4j/2.x/
Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局)。这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出。
Logger
Loggers组件被分为七个级别:
| 级别 | 对应int值 |
|---|---|
| OFF | 0,这是最高等级,为了关闭日志记录 |
| FATAL | 100,指定非常严重的错误事件 |
| ERROR | 200 |
| WARN | 300 |
| INFO | 400 |
| DEBUG | 500 |
| TRACE | 600 |
| ALL | Integer.MAX_VALUE,各级包括自定义级别 |
各个级别的顺序是这样那个的:
OFF < DEBUG < INFO < WARN < ERROR < FATAL < ALL
可以简单地理解为级别越大越重要。
Log4j有一个规则:只输出级别不低于设定级别的日志信息,假设Loggers级别设定为INFO,则INFO、WARN、ERROR、FATAL和ALL级别的日志信息都会输出,而级别比INFO低的DEBUG则不会输出。
Appender
Appender用来规定日志输出的目的地是哪里,可以是控制台,文件,数据库等等。
常见的Appender有以下几种:
org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
在配置文件中是这样配置的:
log4j.appender.appenderName = className
log4j.appender.appenderName.Option1 = value1
…
log4j.appender.appenderName.OptionN = valueN
其中appenderName是Appender的名字,可以随意起,只要满足命名规范就行,Option1,Option2,…,OptionN是这个appender的各种属性。
ConsoleAppender的选项
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
Target=System.err:默认值是System.out。
FileAppender选项
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中
bufferedIO 此标志表示是否需要写入缓存启用。默认设置为false
bufferSize 如果 bufferedI/O 启用,这表示缓冲区的大小,默认设置为8KB
DailyRollingFileAppender选项
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
File=D:/logs/logging.log4j:指定当前消息输出到logging.log4j文件中。
DatePattern=’.’yyyy-MM:每月滚动一次日志文件,即每月产生一个新的日志文件。当前月的日志文件名为logging.log4j,前一个月的日志文件名为logging.log4j.yyyy-MM。
另外,也可以指定按周、天、时、分等来滚动日志文件,对应的格式如下:
‘.’yyyy-MM:每月
‘.’yyyy-ww:每周
‘.’yyyy-MM-dd:每天
‘.’yyyy-MM-dd-a:每天两次
‘.’yyyy-MM-dd-HH:每小时
‘.’yyyy-MM-dd-HH-mm:每分钟
RollingFileAppender选项
Threshold=WARN:指定日志信息的最低输出级别,默认为DEBUG。
ImmediateFlush=true:表示所有消息都会被立即输出,设为false则不输出,默认值是true。
Append=false:true表示消息增加到指定文件中,false则将消息覆盖指定的文件内容,默认值是true。
File=D:/logs/logging.log4j:指定消息输出到logging.log4j文件中。
MaxFileSize=100KB:后缀可以是KB, MB 或者GB**。在日志文件到达该大小时,将会自动滚动,即将原来的内容移到logging.log4j.1文件中。
MaxBackupIndex=2:指定可以产生的滚动文件的最大数,例如,设为2则可以产生logging.log4j.1,logging.log4j.2两个滚动文件和一个logging.log4j文件。
Layout
Layout用来规定日志是以什么样的格式输出,需要输出哪些信息。Layout提供四种日志输出样式,如根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式。
常见的Layout如下:
org.apache.log4j.HTMLLayout(以HTML表格形式布局)
org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)
在配置文件中这样配置的:
log4j.appender.appenderName.layout =className
log4j.appender.appenderName.layout.Option1 = value1
…
log4j.appender.appenderName.layout.OptionN = valueN
HTMLLayout选项
LocationInfo=true:输出java文件名称和行号,默认值是false。
Title=My Logging: 默认值是Log4J Log Messages。
PatternLayout选项
ConversionPattern=%m%n:设定以怎样的格式显示消息。
各种格式化说明如下:
- %p:输出日志信息的优先级,即DEBUG,INFO,WARN,ERROR,FATAL。
- %d:输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,如:%d{yyyy/MM/dd HH:mm:ss,SSS}。
- %r:输出自应用程序启动到输出该log信息耗费的毫秒数。
- %t:输出产生该日志事件的线程名。
- %l:输出日志事件的发生位置,相当于%c.%M(%F:%L)的组合,包括类全名、方法、文件名以及在代码中的行数。例如:test.TestLog4j.main(TestLog4j.java:10)。
- %c:输出日志信息所属的类目,通常就是所在类的全名。
- %M:输出产生日志信息的方法名。
- %F:输出日志消息产生时所在的文件名称。
- %L::输出代码中的行号。
- %m::输出代码中指定的具体日志信息。
- %n:输出一个回车换行符,Windows平台为”\r\n”,Unix平台为”\n”。
- %x:输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
- %%:输出一个”%”字符。
以下是 log4j.properties 文件的一个appender X的语法:
# 根日志记录器(logger)的级别定义为DEBUG并连接附加器命名为X
log4j.rootLogger = DEBUG, X
# 附加器(appender)X是定义为org.apache.log4j.FileAppender并写入到一个名为“log.out”位于日志log目录下
log4j.appender.X=org.apache.log4j.FileAppender
log4j.appender.X.File=${log}/log.out
# 定义的布局模式是%m%n,这意味着每打印日志消息之后,将加上一个换行符
log4j.appender.X.layout=org.apache.log4j.PatternLayout
log4j.appender.X.layout.conversionPattern=%m%n
需要注意的是
- 可以同时指定多个输出目的地,用逗号隔开。
例如:log4j.rootLogger=INFO,A1,B2,C3 - log4j支持UNIX风格的变量替换,如 ${variableName}.
使用的例子:
public class log4jExample{
/* Get actual class name to be printed on */
static Logger log = Logger.getLogger(log4jExample.class.getName());
public static void main(String[] args) throws IOException,SQLException{
log.debug("Hello this is an debug message");
log.info("Hello this is an info message");
}
}
log4j 和slf4j的比较的更多相关文章
- JavaEE SSH框架整合(四) 日志处理Spring结合 log4j、slf4j [转]
1. 加入log4j和slf4j的jar包 2. web.xml: <context-param> <!--log4j配置地址 --> <param-name>lo ...
- log4j+logback+slf4j+commons-logging的关系与调试(转)
log4j+logback+slf4j+commons-logging的关系与调试 从Log4j迁移到LogBack的理由 http://www.tuicool.com/articles/beeeYv ...
- java日志,(commons-loging 、log4j 、slf4j 、LogBack介绍)
如果对于commons-loging .log4j .slf4j .LogBack 等都已经非常清楚了,可以忽略本文.几次解决日志冲突问题时对这几个概念的简单总结,希望对这块基础没有理解透的同学能有所 ...
- SSH框架整合 日志处理Spring结合 log4j、slf4j
1. 加入log4j和slf4j的jar包 2. web.xml: <context-param> <!--log4j配置地址 --> <param-name>lo ...
- SSM框架下结合 log4j、slf4j打印日志
首先加入log4j和slf4j的jar包 <!-- 日志处理 <!-- slf4j日志包--> <dependency> <groupId>org.slf4j ...
- SpringBoot日志logback-spring.xml分环境log4j logback slf4j区别 springboot日志设置
转载. https://blog.csdn.net/qianyiyiding/article/details/76565810 springboot按照profile进行打印日志log4j logba ...
- 日志管理-log4j与slf4j的使用
一.概述 1.log4j: Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件,甚至是套接口服务器.NT的事件记录器.UNIX Sy ...
- java日志组件介绍(common-logging,log4j,slf4j,logback )
转自:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging是apache提供的一个通用的日志 ...
- Log4j、slf4j
1.Log4j 1.1 Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出位置)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志 ...
随机推荐
- org.springframework.core.NestedIOException: ASM ClassReader failed to parse class file - probably du
如果出现类似下面的错误,原因就是JDK版本太高了,我换成1.7就没事了 Caused by: org.springframework.core.NestedIOException: ASM Class ...
- SSH框架搭建最终版【测试、log4j、baseDao】
最详细搭建SSH框架环境 本博文主要是讲解如何搭建一个比较规范的SSH开发环境,以及对它测试[在前面的搭建中,只是整合了SSH框架,能够使用SSH实现功能],而这次是相对规范的. 导入开发包 在Str ...
- Spring - Spring容器概念及其初始化过程
引言 工作4年多,做了3年的java,每个项目都用Spring,但对Spring一直都是知其然而不知其所以然.鄙人深知Spring是一个高深的框架,正好近期脱离加班的苦逼状态,遂决定从Spring的官 ...
- OSGi-入门篇之生命周期层(03)
前言 生命周期层在OSGi框架中属于模块层上面的一层,它的运作是建立在模块层的功能之上的.生命周期层一个主要的功能就是让你能够从外部管理应用或者建立能够自我管理的应用(或者两者的结合),并且给了应用本 ...
- 交互模式下测试python代码及变量的四则运算
在交互模式下,python代码可以立即执行,所以这很方便我们进行代码测试 1.命令窗口,输入python (如果没配置环境变量则需带python安装目录的绝对路径) >>> 这个就是 ...
- java GUI编程二
java基础学习总结--GUI编程(二) 一.事件监听 测试代码一: 1 package cn.javastudy.summary; 2 3 import java.awt.*; 4 import j ...
- spring依赖注入中接口的问题
问题描述:一个接口,有俩个实现类当注入时候名字不同时,会出现不同的情况 action层: @Controller("userAction") @Scope("protot ...
- vue练手小项目--眼镜在线试戴
最近看到了一个眼镜在线试戴小项目使用纯js手写的,本人刚学习vue.js没多久,便试试用vue做做看了,还没完善. 其中包括初始图片加载,使用keywords查找,父子组件之间传递信息,子组件之间传递 ...
- (译)通过 HTML、JS 和 Electron 创建你的第一个桌面应用
原文:Creating Your First Desktop App With HTML, JS and Electron 作者:Danny Markov 近年来 web 应用变得越来越强大,但是桌面 ...
- 最接近原生APP体验的高性能前端框架-MUI
前 言 轻量,原生UI,流畅体验,是MUI的三个特征. 1. 新手指南 快速体验 1. 下载Hello mui App 下载已打包好的Hello mui 手机app,直接在手机上体验mui的 ...