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 ...
随机推荐
- poj 1845 POJ 1845 Sumdiv 数学模板
筛选法+求一个整数的分解+快速模幂运算+递归求计算1+p+p^2+````+p^nPOJ 1845 Sumdiv求A^B的所有约数之和%9901 */#include<stdio.h>#i ...
- Swift - 使用导航条和导航条控制器来进行页面切换
通过使用导航条(UINavigationBar)与导航条控制器(UINavigationController)可以方便的在主页面和多层子页面之间切换.下面通过一个简单“组件效果演示”的小例子来说明如何 ...
- Swift - 属性观察者(willSet与didSet)
属性观察者,类似于触发器.用来监视属性的除初始化之外的属性值变化,当属性值发生改变时可以对此作出响应.有如下特点: 1,不仅可以在属性值改变后触发didSet,也可以在属性值改变前触发willSet. ...
- 使用Jmeter至WebService压力测试
使用Jmeter至WebService压力测试 目中我们使用了Jmeter对webservice进行了压力測试,Apache JMeter是Apache组织开发的基于Java的压力測试工具.用于对 ...
- android自定义实现抽屉SlidingDrawer的功能
最近项目中需要实现上拉功能,首先想到的就是Android本身自带的抽屉SlidingDrawer,最后也实现了不过,出现的问题就是设置背景色问题,handler和content是两个不同的部分,这就造 ...
- RF+Selenium2Library+Sikuli集成环境搭建
Sikuli是通过截图来编写代码的脚本语言,他是对于Selenium不好处理的一些模态窗口.flash等的利器.废话少说,直接开始安装吧.安装RF+Selenium2Library的环境这里就不说了, ...
- ANDROID L——Material Design综合应用(Demo)
转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! Material Design: Material Design是Google推出的一个全 ...
- Caused by: java.lang.ClassNotFoundException: org.aopalliance.intercept.MethodInterceptor
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Fai ...
- hdu 5115 Dire Wolf
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5115 题目分类:区间dp 题意:有n只狼,每只狼有两种属性,一种攻击力一种附加值,我们没杀一只狼,那么 ...
- SLB 权重问题
<pre name="code" class="html">一般配置SLB的时候有个权重0到100,是如何选择数值的? 权重需要您根据后端机器的配置 ...