Java的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
Java的Log系统介绍和切换(转)的更多相关文章
- Java注解--实现动态数据源切换
当一个项目中有多个数据源(也可以是主从库)的时候,我们可以利用注解在mapper接口上标注数据源,从而来实现多个数据源在运行时的动态切换. 实现原理 在Spring 2.0.1中引入了Abstract ...
- [Java] cmd命令行如何切换目录
cmd.exe是微软Windows系统基于WINDOWS上的命令解释程序,类似于微软的DOS操作系统.cmd.exe是一个32位的命令行程序,运行在Windows NT/2000/XP/2003/vi ...
- java中log的应用
log的简单应用 备忘 加入jar包commons-logging-1.1.jar log4j.properties 如下(就放在src根目录底下 名字和位置都不要变) #OFF.FATAL.ERRO ...
- Java 写 Log
. 一个最基本的例子 使用Logging框架写Log基本上就三个步骤 引入loggerg类和logger工厂类 声明logger 记录日志 下面看一个例子 //1. 引入slf4j接口的Logger和 ...
- Java (JDK 多版本切换)—— Windows平台
0. 背景 常常在不同的应用中需要用到不同版本的Java ,需要切换不同JAVA_HOME. 1. 方法 Step 1. 安装不同版本的JDK(JRE),最好都安装在一个Java目录分支下.例如: S ...
- docker容器修改时区(java应用log信息与标准容器时间有八个小时时间差)
在docker容器中运行的java应用打出的日志时间和通过date -R方式获取的容器标准时间有八个小时时间差- 因为docker容器的原生时区为0时区,为了和国内时区保持一致,需要把容器时区调为东八 ...
- java gc log
java full gc 经常带来延迟, 导致性能问题 如下命令使java虚拟机记录gc的log到文件, 帮助分析定位问题. java -Xloggc:./a.log -jar a.jar // ...
- Windows7 配置两个版本的java环境,可自由切换
1. 准备工作 下载jdk: jdk1.7[http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads ...
- java 自定义log类
目录机构如下: package tpf.common; import org.apache.log4j.*; import java.io.File; import java.net.URL; pub ...
随机推荐
- 与众不同 windows phone (3) - Application Bar(应用程序栏)
原文:与众不同 windows phone (3) - Application Bar(应用程序栏) [索引页][源码下载] 与众不同 windows phone (3) - Application ...
- perl 异步请求和JS对比
perl 异步和js对比: /js************** $(function(){ function isPhone(str){ var regex = /[0-9]{11,11}/; ret ...
- MySQL内存表(MEMORY)说明 | 一个PHP程序员的备忘录
MySQL内存表(MEMORY)说明 | 一个PHP程序员的备忘录 MySQL内存表(MEMORY)说明
- [51daifan]来吧,一起书写51daifan的成长史吧-让一部分人先安全起来
对新创项目而言,是idea更重要,还是执行力更重要?在没有用户时,我们该如何冷启动?团队.人.技术.产品.推广和拜春哥,哪一个更重要?到底是什么决定了一个项目的生存或者毁灭? 来吧,一起书写51dai ...
- java Date 和 javascript Date
近期写一个页面.上面要展示下日期. 在Java中生成了Date.然后将这个Date通过velocity送入vm模板其中 代码例如以下: var dates = new Date("$!{pp ...
- DOM4J解析XML文档
Tip:DOM4J解析XML文档 Dom4j是一个简单.灵活的开放源代码的库.Dom4j是由早期开发JDOM的人分离出来而后独立开发的.与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j ...
- cocos2dX 之CCParticle
今天我们来看看粒子特效, 何为粒子特效, 为了模拟燃烧的火焰, 天空飘下来的血环, 滴落的小雨, 这些无规律变化的物体, 我们引进了粒子特效这个名词, 粒子特效的原理是将无数的单个粒子组合使其呈现出固 ...
- 知识网之C++总结
米老师常说的一句话:构造知识网. 立即要考试了.就让我们构造一下属于C++的知识网.首先从总体上了解C++: 从图中能够了解到,主要有五部分.而当我们和之前的知识联系的话,也就剩下模板和运算符重载以及 ...
- 墙体裂缝推荐的情况下驱动的PhoneGap入门,早看早收据
清华大学出版社推出<构建跨平台APP:PhoneGap移动应用实战> 零门槛的学习APP发展 刮 进步 20以上示范样本APP 3项目APP 台à跨终端à移动开发 完美生命周期:搭建好开发 ...
- kobox : key_wq.c -v1 如何使用工作队列 workqueue
kobox: key_wq.c - v1 说明: TQ2440主要驱动因素,四个按键驱动的处理 key_wq.c和key.c类别似,与key.c之间的差异的主要驱动力: key.c使用计时器,在中断发 ...