log4j logback slf4j,log4j slf4j 区别

  log4j logback slf4j,log4j slf4j 区别

  前言Java帝国提供了集合、线程、IO、网络等常用功能。在其诞生之初。吸引了大量C和C领地的程序员加入进来,却有意无意的忽略了一个重要的功能:输出日志。

  对于这一点,IO部长其实很清楚。日志是一个很重要的东西,因为程序运行之后,基本就是一个黑匣子。如果程序的行为与预期的不一致,那就是Bug。如何定位这个Bug?

  学生可以使用两种工具。第一种是一步一步调试,一步一步跟踪检查代码中变量的值。这种方法费时费力,只能在程序员的机器上使用。

  二是在特定的地方打印日志,有助于通过日志的输出快速定位。尤其是当代码在生产环境中运行时,日志信息更是必不可少。不然出了事,我们就两眼一抹黑了。从哪里可以找到问题?不能让主体把自己变成一个线程,进入系统执行?

  但是IO部长也有自己的小打算:journal我就不能用我的system.out.println(.)?我还提供了System.err.println不是吗?

  在IO部长的阻挠下,从帝国的第一任国王到第三任国王,JDK都没有提供与原木相关的工具包。受试者不得不忍受使用System.out.println向控制台输出日志和所有信息,使其成为一堆垃圾。

  张家村张家村的电商系统也不能幸免,自然遇到了log的问题。经验丰富的老村长厌倦了System.out.println输出的大量不知所云的无用信息看到村民们整天和这些System.out作斗争,他把小张叫来,命令他设计一个通用的日志处理系统。

  小张在消息队列和JMS的设计上花了很多时间,积累了丰富的经验。从那以后,他一直在实现业务代码和CRUD。张开玩笑说自己整天就是一个HTML填充员。这一次,她一定要看看自己的设计功力!

  老村长给小张的要求是:1。日志消息可以打印到控制台,输出到文件,甚至通过邮件发送出去(例如,生成环境错误的消息)。

  2.日志内容要格式化,比如纯文本、XML、HTML等等。

  3.对于不同的Java类、不同的包和不同级别的日志,应该可以灵活地输出到不同的文件。

  比如对于com.foo的包,所有日志都输出到foo.log文件;对于com.bar的包,所有文件都输出到bar。日志文件;对于错误级别的所有日志,所有日志都输出到errors.log文件。4.日志是可以分级的,有些日志是纯调试的,在本地或者测试环境下使用,方便程序员调试,在生产环境下完全不需要。一些日志描述了错误。如果生产环境中存在错误,必须记录下来,以帮助后续分析。

  小张仔细看了看,拍着胸脯对老村长说:“没问题,明天我总让你看看结果。”

  小张的设计老村长走后,小张开始分析需求,祭出“面向对象的设计方案”,试图从村长的需求中抽象出一些概念。

  首先,记录一个日志,你肯定需要一个类来表达一个日志的概念。这个类应该至少有两个属性,一个是时间戳,另一个是消息本身。我们称之为LoggingEvent。记录日志就像记录一个事件。

  其次,日志可以输出到不同的地方,比如控制台、文件、邮件等。这个可以抽象,不就是写到不同的目的地吗?可以叫LogDestination?

  好吧,让我们简单点。让我们称之为Appender,这意味着您可以继续追加日志。

  至于第二条的日志内容,可以格式化,完全比画个瓢,定义个格式化器接口来格式化消息要好。

  没错,Appender应该引用Formatter,这样LoggingEvent记录就可以被格式化,以后再发送。

  第三个要求难倒了小张。不同的类和包输出不同的目的地?“目的地”这个概念是由Appender表达的。是否要关联不同的类、包和附加器?不,你不能!

  需要一个新概念。这是什么概念?站在用户的角度想想。村民要想得到原木,首先要有所获。这东西能叫Logger吗?灵感的火花一闪,被小张抓住了:当你得到Logger的时候,要传入类名或者包名!

  区分类、包,然后将日志器与附加器关联起来,灵活设置日志的目的地。而且,一个logger可以有多个appenders,同样的日志消息可以输出到多个地方。完美!

  小张很快画出了核心类的类图:

  挺好看的,小张陶醉在自我欣赏中。

  再接再厉,设计好第四个需求。原木要分等级。这很简单。定义一个优先级类,它定义了五个常量DEBUG、INFO、WARN、ERROR、FATAL。代表五个不同的层次是可以的。当然我有五个级别,最低级别的DEBUG,最高级别的FATAL。

  还可以给Logger添加一些辅助的编程方法,比如logger.debug (…)、logger.info (…)、logger.warn (…)等等,方便村民以后输出各种级别的日志。

  等一下,老村长还说“所有的错误级别日志都会输出到errors.log文件”。这样的要求似乎被忽略了。

  这很容易做到。只要给Appender加一个属性,就叫优先级。如果用户要输出的日志处于调试级别,但是FileAppender的优先级处于错误级别,那么这个日志不需要在这个FileAppender中输出,因为错误级别高于调试级别。

  类似地,可以将优先级属性添加到Logger类中,该属性可以由用户设置。如果记录器的优先级为ERROR,并且用户调用记录器的调试器方法,则不会输出调试后的消息。

  小张全身心地投入到设计中。他看了看时间,已经快午夜了。休息一下,明天向村长报到。

  正交第二天,小张展示了Logger事件的类和接口,Logger,Appender,Formatter,Priority等。由他自己设计给老村长。老村长捻着胡须,满意地点点头:“不错,不错。和上次相比,有了很大的进步。你知道我实际上在你的需求上给了你指导吗?”

  “导游?什么指导?”

  “就是让你在正交的方向上努力。”

  “正交?”

  “如果把Logger、Appender、Formatter看成坐标系中的X轴、Y轴、Z轴,看这三个能不能独立变化,互不影响?”

  “我参加比赛,这是真的。我可以任意扩展Appender接口,而不会影响Logger和Formatter。无论多少个记录器都能影响Appender和Formatter,这就是正交性?”

  “是的,当你从系统中提取正交概念时,这是极其强大的,因为变化被封装在一个维度中,你可以随意组合这些概念,而不是变成意大利面条一样的代码。”

  听到村长理论的升华,小张激动得直搓手。

  “嗯,你已经意识到这个设计了,对吗?对了,你叫什么名字?”村长问道

  “我打算叫他Log4j,意思是Java的Log”

  “是的,就这么定了”

  小张又花了两个月开发Log4j。Log4j因其良好的设计和卓越的性能,不仅被张家村的人们使用,也受到爪哇帝国众多村镇和部落的喜爱。

  后来张家村在阿帕奇部落开放了Log4j,吸引了无数人帮忙测试,扩充,改进,很快成为帝国最受欢迎的日志工具。

  张的村庄建议帝国将Log4j纳入,但帝国低效的官僚机构实际上拒绝了。当这个消息传到大臣伊俄耳中时,他不禁感叹:唉,我失去了一个向他求爱的绝佳机会。现在唯一的办法就是赶紧打皇帝,在官方提供一套,让臣民用官方版。

  到了第四代王者(JDK1.4),受试者终于看到了帝国提供的java.util.logging包,也是用来记录日志的,而且Logger、Formatter、Handler、Log4j的核心概念都很相似,但是已经晚了。Log4j早已深入人心,不可撼动。

  Log4j的最后,Apache开源后,小张渐渐有些落寞。他忍不住又写了一个工具,叫logback。根据以前的经验,这个logback比log4j更快。

  如今的伐木界有很多选择。除了java.util.logging、log4j之外,还有logback、tinylog等其他工具。

  小张想了想。这么多日志工具,用户想切换怎么办?不想用log4j,可以切换到logback吗?

  我最好提供一个抽象层。用户用这个抽象层的API写日志,并不关心底层用什么日志工具,所以可以移植。

  小张称这个抽象层为Java的简单日志门面,简称SLF4J。

  对于Log4j、JDK日志、tinylog等工具,需要一个适配层将SLF4J的API转换成具体工具的调用接口。

  由于Logback工具也是小张创建的,直接实现了SLF4J的API,甚至不需要适配层。使用起来很快,效率最高。SLFJ4 Logback成为了很多人的最爱,大大超越了Apache常用日志Log4j。

  后记:本文主要想谈谈测井仪器的历史和现状,尤其是Log4j岩心的设计理念。

  本文中的小张其实就是Ceki Glc,他开发了Log4j、logback、slfj4,为Java的日志事业做出了卓越的贡献。

  版权归作者所有:来自博客作者为温度原创作品。转载请联系作者获得授权,否则将追究法律责任。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: