java日志和SLF4J随想-Java-优质IT资源分享社区

admin
管理员
管理员
  • UID1
  • 粉丝29
  • 关注4
  • 发帖数581
  • 社区居民
  • 忠实会员
  • 原创写手
阅读:180回复:0

  java日志和SLF4J随想

楼主#
更多 发布于:2016-05-21 23:09

java日志和SLF4J随想

 本文漫谈java中的日志:曾经如何运用日志,以及相似SLF4J的库为咱们带来了什么。

日志是创立软件时的基本需求之一,多见的用例如:

软件开发过程中的调试

出产环境下确诊bug

出于安全意图而跟踪拜访

创立计算运用的数据

等等

不论用途为何,日志都应当是详尽、可装备和牢靠的。

前史

在前期,java日志运用System.out.println(),

System.err.println() 或

e.printStackTrace()。调试信息输出到规范输出System.out,过错信息输出到规范过错System.err。在出产环境中,二者都被重定向:前者重定向到null(注:不输出),后者重定向到需求的日志文件。这种做法够用但有很大的缺点:不行装备。它是个是或否的开关,要么全记录要么完全不,不能在某一层或某个包上重视详细的日志。

Log4J充当了救星,它满意了大家对日志结构的简直一切需求。它引入了很多日志结构中今日仍在运用的概念(它是我首个运用的结构所以请原谅我若某个概念本来不是它创造的):

Logger的概念,每个logger能够独自装备

Appender的概念,每个appender能够将日志输出到它想要的任何地方(文件、数据库、消息等等)

Level的概念,开发人员能够独自装备是不是输出每条日志

以后,Sun意识到需求在JDK中供给日志特性,它没有直接运用Log4J,而是仿照Log4J创立了自个的API。但是,新API的完成度不及Log4J。假如你想运用JDK1.4的日志API,你也许有必要创立自个的Appender-在java

API中叫Handler-因为能直接用的日志意图地只要控制台和文件。

运用这些结构都需求多份装备,因为不论你挑选哪个,至少有一个你的依靠会运用另一个。Apache

Commons

Logging是一个将它自个与日志结构衔接的API桥梁。库应当调用commons-logging,这么库运用的实际结构和你的工程是相同的,而不是它强行运用的。实际不老是这么,所以Commons

Logging没有解决双重装备疑问。此外,Commons Logging还会遇到类加载的疑问,致使NoClassDefFoundError报错。

最终,Log4J核心的开发者因为此处不方便细说的原因退出了Log4J工程。他创立了另一个日志结构,这个本应成为Log4J第二版的日志结构被命名为SLF4J。

一些古怪的现实

以下是前述结构困惑我的一些现实,它们不一定都是缺点但值得指出来:

Log4J经过maven强行依靠JMS,

Mail和JMX,意味着假如你不嫌费事特意排除它们那这些就会呈现在你工程的类途径中。

相似地,Commons

Logging经过maven强行依靠Avalon(另一个日志结构),Log4J, LogKit和Servlet API(!)

Log4J中一直包括一个Swing日志查看器,即便它是用在无需展示的环境中,例如批处理或运用服务器。

Log4J 1.3版的主页重定向到1.2版,而2.0版还在实验室阶段。

挑选哪个结构?

Log4J是能够挑选的结构(对大多数)但它不再开发了。1.2版是参阅,1.3版抛弃了而2.0还处在它的前期阶段。

Commons

Logging是作为库的好挑选(比较运用),但我无法忍受类加载器的疑问,一次就够了(最终,我抛开Commons Logging直接用了Log4J).

JDK1.4日志是规范并且不存在多版本共用的疑问,但它短少太多特性,假如不贰次开发如数据库适配器或其它就不能运用。太糟了。。。但仍未答复这个疑问:挑选哪个结构?

近来,我公司的架构师决议运用SLF4J,为什么会挑选它?

SLF4J

SLF4J不及Log4J运用遍及,因为很多架构师和开发者了解Log4J而不知道SLF4J,或不重视SLF4J而坚持运用Log4J。此外,Log4J满意了很多工程的一切日志需求。不过,风趣的是,Hibernate运用了SLF4J。它拥有一些Log4J没有的夸姣特性。

简略的语法

看这个Log4J示例:

Logger.debug("Hello " + name);

因为字符串拼接的疑问(注:上述句子会先拼接字符串,再根据当时等级是不是低于debug决议是不是输出本条日志,即便不输出日志,字符串拼接操作也会履行),很多公司强行运用下面的句子,这么只要当时处于DEBUG等级时才会履行字符串拼接:

if (logger.isDebugEnabled()) {

LOGGER.debug(“Hello ” + name);

}

它避免了字符串拼接疑问,但有点太繁琐了是不是?相对地,SLF4J供给下面这么简略的语法:

LOGGER.debug("Hello {}", name);

它的形式相似第一条示例,而又没有字符串拼接疑问,也不像第二条那样繁琐。

SLF4J API和完成

此外,SLF4J极好地解耦了API和完成,所以你在开发环境和出产环境中运用它的API都能够极佳地适配。例如,你能够强行运用SLF4J的API,而坚持出产环境中用了几年的旧的Log4J.properties文件。SLF4J的日志完成是LogKit。

SLF4J桥接

SLF4J具有桥接的特性,你能够移除你的工程及其依靠组件运用的一切Log4J和commons-logging包,只运用SLF4J。

SLF4J为每一种日志结构供给一个JAR包:它仿照其它日志结构的API但将完成引向SLF4J的API(进而运用环境中实在的结构)。一点正告:当心不要让classpath中一起呈现同一种日志的桥接库和完成库,否则会陷入循环。例如,运用Log4J桥接库时,每个Log4J的API被引向SLF4J,假如SLF4J的Log4J完成一起存在,会再次引向Log4J,这么循环下去。

SLF4JAPI和Log4J完成

归纳一切思考,我的主张是运用SLF4J的API和Log4J的完成。这么,你仍像曾经相同装备Log4J,但调用更简略的SLF4J接口。要这么做,你需求:

操作位置描绘

参加classpathslf4j-api.jar*主API,没有它就无法运用SLF4J

slf4j-log4j.jar*SLF4J的Log4J完成

jul-to-slf4j.jar*答应重定向 JDK 1.4日志到 SLF4J

jcl-over-slf4j.jar*重定向commons-logging调用到SLF4J

从classpath移除commons-logging.jar*会跟

jcl-over-slf4j.jar里的commons-logging API抵触

SLF4JBridgeHandler.install()**主运用重定向JDK

1.4日志调用到SLF4J

* Jar名也许包括版本

**只在你需求单一进口或少量调用

假如你的运用在运用服务器中运转,你也许需求修正它的库和/或装备来达到以上修正。

更多:

SLF4J项目

Log4J项目

Commons Logging项目

Commons Logging类加载疑问

优质IT资源分享社区为你提供此文。

本站有大量优质Java教程视频,资料等资源,包含java基础教程,高级进阶教程等等,教程视频资源涵盖传智播客,极客学院,达内,北大青鸟,猎豹网校等等IT职业培训机构的培训教学视频,价值巨大。欢迎点击下方链接查看。

java教程视频

优质IT资源分享社区(www.itziyuan.top)
一个免费,自由,开放,共享,平等,互助的优质IT资源分享网站。
专注免费分享各大IT培训机构最新培训教学视频,为你的IT学习助力!

!!!回帖受限制请看点击这里!!!
!!!资源失效请在此版块发帖说明!!!

[PS:按 CTRL+D收藏本站网址~]

——“优质IT资源分享社区”管理员专用签名~

本版相似帖子

游客