当前位置: 首页 > 科技观察

为什么阿里巴巴禁止工程师直接使用日志系统(Log4j、Logback)中的API

时间:2023-03-13 03:37:09 科技观察

?作为一个Java程序员,我想很多人都知道日志对于一个程序的重要性,尤其是对于web应用来说。很多时候,日志可能是我们了解应用程序性能的唯一方式。因此,日志在JavaWeb应用中非常重要,但是很多人认为日志输出只是一件简单的事情,所以往往会忽略与日志相关的问题。在接下来的几篇文章中,我将介绍这个容易被大家忽略,同时也容易导致失败的知识点。Java语言之所以强大,是因为其成熟的生态系统。包括日志功能,有很多成熟的开源框架可以直接使用。首先我们来看看目前被广泛使用的框架有哪些。常用的日志框架j.u.lj.u.l是java.util.logging包的缩写,是JDK在1.4版本引入的Java原生日志框架。JavaLoggingAPI提供了七个日志级别来控制输出。七个级别是:SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST。Log4jLog4j是Apache的一个开源项目。通过使用Log4j,我们可以控制日志信息传输的目的地是控制台、文件、GUI组件,甚至是socket服务器、NT事件记录器、UNIXSyslog守护进程等;我们还可以控制每条日志的输出格??式;通过定义每条日志信息的级别,我们可以更详细地控制日志的生成过程。Log4也有七个日志级别:OFF、FATAL、ERROR、WARN、INFO、DEBUG和TRACE。最有趣的是,这些可以通过配置文件灵活配置,无需修改应用代码。LogBackLogBack也是一个非常成熟的日志框架。其实LogBack和Log4j是一个人创造的,这个人就是CekiGülcü。Logback目前分为三个模块:logback-core、logback-classic和logback-access。logback-core是其他两个模块的基础模块。logback-classic是Log4j的改进版本。此外,logback-classic完全实现了SLF4JAPI,因此您可以轻松地将其替换为其他日志系统,例如Log4j或j.u.l。logback-access访问模块与Servlet容器集成,提供通过Http访问日志的功能。Log4j2之前已经介绍过Log4j,这里单独介绍一下Log4j2。之所以要单独拿出来而不是和Log4j一起介绍,是因为笔者认为Log4j2不仅仅是Log4j的升级版,而是从零开始。最后重写了,可以认为是两个完全不同的框架。关于Log4j2为Log4j解决了哪些问题,Log4j2相对于Log4j、j.u.l、logback有哪些优势,我们会在后续文章中进行介绍。禁止直接使用Log框架API?前面介绍了四种日志框架,也就是说,当我们要在应用中打印日志时,可以使用以上四种类库中的任意一种。比如要使用Log4j,只需要在代码中依赖Log4jjar包,配置配置文件,使用其API打印日志即可。不知道有多少人看过《阿里巴巴Java开发手册》,其中一个规范做了一个“强制”的要求:据说上面四种常用的日志框架是为了方便Java应用记录日志,何乐而不为呢?让他们在应用程序中直接使用它的API怎么样?这里推荐的SLF4J是什么?什么是门面模式?什么是原木门面?日志门面是门面模式的典型应用。FacadePattern,又称外观模式,其核心是:外界与一个子系统的通信必须通过统一的外观对象进行,使子系统更易于使用。就像上面介绍的几个日志框架一样,每个日志框架都有自己独立的API。要使用相应的框架,就必须使用其相应的API,这大大增加了应用代码与日志框架的耦合度。.为了解决这个问题,就是在日志框架和应用之间架起一座沟通的桥梁。对于应用来说,无论底层日志框架如何变化,都不需要任何感知。只要门面服务够好,可以随意换成其他日志框架,应用可以直接上线,不用修改任何一行代码。软件开发领域有一句话:计算机科学领域的任何问题都可以通过增加一个间接中间层来解决。门面模型就是这句话的典型做法。为什么需要日志门面前面提到的一个重要原因是为了屏蔽应用程序中底层日志框架的具体实现。这样即使哪天要改代码的日志框架,也只需要修改jar包,顶多改一下日志输出相关的配置文件。这是应用程序和日志框架之间的解耦。可能有人会问,我改了日志框架,应用不用改,那日志门面还需要改吗?要回答这个问题,我们先举个例子,然后打破门面模式重新解释。原木立面就像餐厅的服务员,原木框架就像后厨的厨师。对于客户应用来说,去饭店点餐,只需要跟服务员说要一盘西红柿炒鸡蛋就行,后厨的一切我都不管。因为虽然厨师从把这道菜叫“西红柿炒鸡蛋”的厨师A变成了叫这道菜“西红柿炒鸡蛋”的厨师B。不过顾客不用管,只需要将“番茄炒鸡蛋”的单子交给服务员,服务员就会翻译给厨师。因此,对于一个懂“番茄炒蛋多种名称”的服务员来说,不管后厨的厨师怎么变,都能准确地帮助用户下单。同理,一个设计良好、功能全面的日志门面,也应该天然兼容各种日志框架。因此,当底层框架更换时,日志门面几乎不需要改动。以上就是原木门面比较重要的好处之一——解耦。常用的日志门面介绍完日志门面的概念和好处,我们来看看Java生态中有哪些好的日志门面实现。SLF4JJavaSimpleLoggingFacadeforJava(简称SLF4J)是一组封装了Logging框架的接口程序,以外观方式实现。可以在软件部署期间决定要使用的日志记录框架。目前主要支持的框架有JavaLoggingAPI、Log4j、logback。根据麻省理工学院许可发布。SLF4J的作者是CekiGülcü,他是Log4j和Logback的作者,他声称SLF4J比Log4j更高效,比ApacheCommonsLogging(JCL)更简单、更稳定。事实上,SLF4J其实只是一个门面服务。它不是一个真正的日志框架。真正的日志输出的实现还是依赖于Log4j、logback等日志框架。由于SLF4J比较常用,这里我就多用一些篇幅,然后简单分析一下SLF4J,主要是和Log4J进行对比。与Log4JAPI相比,SLF4J有以下优点:Log4j提供了六个日志级别:TRACE、DEBUG、INFO、WARN、ERROR和FATAL,但是SLF4J认为ERROR和FATAL之间没有实质性的区别,所以去掉了FATAL级别,只剩下另外五个。大多数人会在程序中写logger.error(exception)。实际上,此时Log4j会把这个异常放到string中。真正的写法应该是logger(message.exception);而SLF4J不会让程序员犯这个错误。Log4j间接鼓励程序员使用字符串加法(这种写法有性能问题),而SLF4J不会有这个问题,可以使用logger.error("{}is+serviceid",serviceid);使用SLF4J可以方便的使用它提供的各种集合实现jar。(类似于commons-logger)从commons-logger和Log4j合并很方便。SLF4J还提供了一个swing工具来帮助您完成这种合并。SLF4J只支持MDC,不支持NDC。提供字符串内容替换的功能会更高效,如下解释://在传统的字符串生成方式中,如果没有需要记录的debug级别信息,会浪费时间生成不必要的信息logger.debug("Therearenow"+count+"useraccounts:"+userAccountList);//为了避免上述问题,我们可以先查看是否开启了Debug信息记录功能,但是程序的代码会比较复杂if(logger.isDebugEnabled()){记录器。debug("Therearenow"+count+"useraccounts:"+userAccountList);}//如果不开启Debug级别,则不会产生不必要的字符串,可以保持程序代码简洁logger.debug("Therearenow{}useraccounts:{}",计数,userAccountList);commons-loggingApacheCommonsLogging是一个基于Java的日志记录实用程序和一个用于日志记录和其他工具包的编程模型。它通过一些其他工具提供API、日志实现和包装器实现。commons-logging和SLF4J的功能类似,主要是作为日志门面使用。提供更友好的API工具。总结在Java生态中,围绕日志有很多成熟的解决方案。关于日志输出,主要有两种工具。一种是日志框架,主要用于日志输出,比如输出到哪个文件,日志格式是什么等等。另一类是日志门面,主要是一套通用的API,用来屏蔽各种日志框架之间的差异。因此,对于Java工程师来说,关于日志工具的使用,最好的做法是在应用中使用Log4j+SLF4J这样的组合进行日志输出。这样做最大的好处是业务层的开发不需要关心底层日志框架的实现和细节,编码时也不需要考虑日后更换框架的成本。这也是门面模式带来的好处。总之,请不要在Java代码中使用Log4j等日志框架的任何API,而应直接使用SLF4J的日志门面。【本文为专栏作家霍利斯原创文章,作者微信公众号Hollis(ID:hollishuang)】点此阅读更多本作者好文