Java的Log系统介绍和切换(转)

简介: Java的log系统比较繁杂。在这里梳理一下。本文只涉及log系统介绍和处理log系统之间的切换。不涉及如何配置和使用。   具体的log系统 Log4j:准确的说是log4j 1.x版。是之前使用最广泛的log系统。

Java的log系统比较繁杂。在这里梳理一下。本文只涉及log系统介绍和处理log系统之间的切换。不涉及如何配置和使用。

 

具体的log系统

Log4j:准确的说是log4j 1.x版。是之前使用最广泛的log系统。

Logback:Log4j的作者另立炉灶写的新版log,比起log4j性能更好。具体的对比可以参考http://www.oschina.net/translate/reasons-to-prefer-logbak-over-log4j 

JUL:Java Util Logging,是java 1.4以来自带的一个logging系统。相信用的人应该不多吧……

 

以上三个log系统是实打实的做事情的log系统,需要相应的配置来制定如何处理log等。

 

Log Facade系统

实际情况下,一个项目可能不想具体依赖于一种具体的log系统(比如log4j)。尤其是对于开源的中间件,类库等。如果一个开源的类库在代码里写了用log4j,那所有用到这个类库的代码都必须跟log4j扯上关系了(注意,没说必须要用log4j哦,后文会涉及y)。

更可能的是,应用依赖的类库有的用log4j,有的用logback,局面就会比较混乱。这会让应用无法方便的统一管理log系统。

 

应运而生的就是下面要介绍的这种log facade组件。或者说是一个bridge,一个包装,一个adapter……总之是做于log落地无关的事情的。它的作用就是将代码和log系统隔离,提供一个统一的接口,然后把log请求adapter到具体的log实现系统(上文中提到的)。

JCL:又叫做Common Logging,apache common logging,Jakarta Commons Logging。都是一个东西。

SLF4j:Simple Log Facade 4 Java。这个系统是log4j,logback的作者实现的。

 

SLF4j+logback

在具体的项目中,slf4j+logback是个不错的搭配。简单介绍一下这个组合。slf4j是个门面,在具体的代码中,它会尝试加载org.slf4j.impl.StaticLoggerBinder这个类。然后通过这个类的方法创建LogFactroy,以及各种log。所以StaticLoggerBinder就是连接slf4j和具体实现的桥梁。每种具体的实现,都要提供一个StaticLoggerBinder,来让slf4j找到具体的实现。

 

动态绑定/加载实现

logback和log4j都提供了StaticLoggerBinder(毕竟是一个人做的嘛……)。如果使用logback,就需要在cp里加入logback-classic(外围+扩展,StaticLoggerBinder就在这里面),logback-core(核心)。如果使用log4j,就需要slf4j-log4j12(版本即log4j的版本)。当然还少不了slf4j的jar包slf4j-api。

 

这样的话,应用程序中就只会引入slf4j的类。而具体实现则是slf4j负责打理的(加载Binder,Binder会负责触发log系统初始化等)。应用和具体的log系统就解绑了。类库使用了slf4j之后,就不必担心自己的选择会影响应用了。应用如果把log4j的相关jar包放在cp里,那就会是使用log4j。同样也可以使用logback。

 

如果cp里有多个Binder,就可能会看到如下的错误提示:

SLF4J: Class path contains multiple SLF4J bindings.

SLF4J: Found binding in [jar:file:/D:/Users/mzang/.m2/repository/org/slf4j/slf4j-log4j12/1.7.5/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: Found binding in [jar:file:/D:/Users/mzang/.m2/repository/ch/qos/logback/logback-classic/1.0.13/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.

SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

 

p.s. Common Logging和slf4j异曲同工,只是具体实现方式不同。

 

更麻烦的事——切换Log系统

如果上面的东西还好理解,那么下面的事情就有点搞了。

在实际情况下,可能我们会有这样的需求。一个组件使用了log4j/jul/common log。但是我们想统一到使用slf4j + logback。举例来说,如果我们的应用一直用slf4j,结果引入的一个新类库使用了common logging。比较好的处理方式是让slf4j接替 common logging。或者说,让请求都落到slf4j上。

 

jcl-over-slf4j这个包可以完成这个任务。具体的步骤是,把common logging的jar包从cp里删掉,然后把jcl-over-slf4j放入cp。这个jar包中的类和common logging中的类名,方法名等完全一样,只是在具体的方法中,把所有的请求都暗渡陈仓的转移到了slf4j上。

 

同样还有log4j-over-slf4j,可以解决在代码中写了使用log4j的情况。只要用这个jar包替代log4j的jar包就可以了(还有一些细节,比如,如果程序中显示的调用了log4j中的一些类,appender什么的,那就没办法了,如果是规规矩矩的使用log4j.properties,那就没啥大问题)。

 

对于jul就复杂一点,因为不能把java中自带的类删了。所以jul-to-slf4j的做法是用自己的Hander(JUL处理日志的接口)作为root,同时删除所有的其它logger。这样就相当于用个二传手把所有的log通过这个硬塞进来的Handler,委托给了slf4j,然后slf4j再寻找实现,bulabula就跟前面一样了。

 

slf4j官网上有一个关于这方面的系统阐释。主要就是这个图。我尝试加了一下中文注释:

原地址:http://www.slf4j.org/legacy.html


 

那一大段话:

这个图展示了出于方便和权宜之下,所有可能的重定向和绑定。重定向只有在必须的时候才做。比如说,把jul重定向到slf4j,但是系统中又根本没用到jul,这样的重定向是没意义的。

 

总结一下:

负责提供slf4j绑定的jar包:

slf4j-log4j12

slf4j-jdk14

logback-classic

他们需要和具体的、对应的、版本一致的实现同时出现在cp中。

 

负责重定向到slf4j的:

jcl-over-slf4j

log4j-over-slf4j

jul-to-slf4j

 

他们需要替换掉原来的log系统的jar包(jcl和log4j),或者需要初始化一下(jul-to-slf4j)

 

http://deepnighttwo.iteye.com/blog/2039553

http://blog.csdn.net/longyulu/article/details/38685503

 

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
4天前
|
JavaScript Java BI
Java毕设之新生报到系统的设计与实现
Java毕设之新生报到系统的设计与实现
11 3
|
1天前
|
数据采集 前端开发 Java
Java医院绩效考核系统源码maven+Visual Studio Code一体化人力资源saas平台系统源码
医院绩效解决方案包括医院绩效管理(BSC)、综合奖金核算(RBRVS),涵盖从绩效方案的咨询与定制、数据采集、绩效考核及反馈、绩效奖金核算到科到组、分配到员工个人全流程绩效管理;将医院、科室、医护人员利益绑定;全面激活人才活力;兼顾质量和效益、长期与短期利益;助力医院降本增效,持续改善、优化收入、成本结构。
4 0
|
1天前
|
Java
排课系统【JSP+Servlet+JavaBean】(Java课设)
排课系统【JSP+Servlet+JavaBean】(Java课设)
13 5
|
2天前
|
存储 Java API
java对接IPFS系统-以nft.storage为列
java对接IPFS系统-以nft.storage为列
11 2
|
2天前
|
监控 前端开发 Java
Java基于B/S医院绩效考核管理平台系统源码 医院智慧绩效管理系统源码
医院绩效考核系统是一个关键的管理工具,旨在评估和优化医院内部各部门、科室和员工的绩效。一个有效的绩效考核系统不仅能帮助医院实现其战略目标,还能提升医疗服务质量,增强患者满意度,并促进员工的专业成长
9 0
|
2天前
|
Java 云计算
Java智能区域医院云HIS系统SaaS源码
云HIS提供标准化、信息化、可共享的医疗信息管理系统,实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。优化就医、管理流程,提升患者满意度、基层首诊率,通过信息共享、辅助诊疗等手段,提高基层医生的服务能力构建和谐的基层医患关系。
16 2
|
3天前
|
前端开发 Java 关系型数据库
Java医院绩效考核系统源码B/S架构+springboot三级公立医院绩效考核系统源码 医院综合绩效核算系统源码
作为医院用综合绩效核算系统,系统需要和his系统进行对接,按照设定周期,从his系统获取医院科室和医生、护士、其他人员工作量,对没有录入信息化系统的工作量,绩效考核系统设有手工录入功能(可以批量导入),对获取的数据系统按照设定的公式进行汇算,且设置审核机制,可以退回修正,系统功能强大,完全模拟医院实际绩效核算过程,且每步核算都可以进行调整和参数设置,能适应医院多种绩效核算方式。
22 2
|
4天前
|
JavaScript 小程序 Java
基于java的少儿编程网上报名系统
基于java的少儿编程网上报名系统
11 2
|
4天前
|
JavaScript 小程序 Java
Java毕设之在线医疗服务系统的设计与实现
Java毕设之在线医疗服务系统的设计与实现
8 3
|
4天前
|
JavaScript 小程序 Java
Java毕设之KTV点歌系统
Java毕设之KTV点歌系统
12 2