有相当多的考虑因素使日志记录“比乍一看更复杂”,(因此经历了数十年的激烈内斗!
关注点分离
在一天结束时,代码“发送日志数据”,而该数据“最终在某个地方”。但它最终走向何方取决于收集它的目的。使情况变得非常复杂的是,现代软件由各种组件组成,并且它们都可能需要记录。
让我们考虑一个最坏的情况:所有组件都使用。至少所有语句都是按执行顺序排列的,但是要辨别哪个组件生成了每个输出可能并不简单。某些组件对于使用它们的上下文可能过于冗长。System.out#println(String)
让我们考虑下一个最坏的情况:所有组件都做出自己的安排来控制其日志记录行为和目标。管理员可能必须为单个软件配置数十个日志系统。现在,日志语句不在一起,并且它们不按顺序排列。希望他们都有一个一致的时间戳策略!
我们想要介于两者之间的东西:代码可以说“记录这个”,管理员可以控制它最终的位置。
过于简短的历史
输入Log4J v1,它解决了“级别”,“附加器”,“过滤器”,“布局”和“上下文”概念的问题......由分层“记录器命名空间”支持的概念体系结构(包括一种自然利用 Java 包命名空间的方法),以及易于管理的配置机制。
这一切都很好,很好...只要软件中的所有组件都依赖于相同的版本!曾经有一段时间,这些事情在不断变化。SLF4J的主要贡献是从组件开发人员的角度将这些概念“强化”为稳定的API,而不会损害管理员完成其工作的选项。图书馆可以依靠SLF4J的“门面”,期望他们只需在堆栈中调用几个调用,他们就会与“实现”进行对话。管理员可以选择适合他们的内容,将日志组合成他们关心的连贯记录。
(当您的软件在容器中运行时,情况会更加复杂,并且容器有自己的日志记录需求,并且您甚至不是在容器中运行的同一个应用程序......Tomcat 的 JULI 日志记录 - 用于自己的内部日志记录 - “摆脱”在类加载器子上下文中运行的应用程序。
神秘地蔑视Log4J的工作,Java社区进程决定在 中实现大致相同的概念架构,而细节上的灵活性可以说是降低的。然而,由于它本质上是SLF4J语义丰富性的子集,因此很容易使SLF4J成为一个门面。java.util.logging
j.u.l
j.u.l
Apache的Commons Util Logging可能不是很有必要。Ceki自己的Logback引入了Log4J v1当时没有的管理功能 - 不仅是SLF4J的实现并解决了所有那些非常真实的类加载器难题,而且还为管理员提供了一些吸引人的功能。
不同情况的日志记录
但是日志记录是在许多不同的上下文中完成的。将这些消息分解为超慢的I / O,而不会过度阻塞线程,并且除非需要,否则无需支付计算日志消息的代价,并在多线程上下文中生成一致的日志......这些事情都很重要。(这就是为什么不经常使用的原因!java.util.logging
有时,所需的优化会影响概念体系结构,而概念体系结构又必须影响开发人员端 API。例如,如果日志消息由于过滤而最终成为no-op,则关闭提供的机会肯定会加快速度。需要考虑SLF4J.next或其他一些API才能使用该功能,并且Log4J2不必排除在此决定之外。由于API部分是SLF4J提供的概念超集,因此很容易使其成为SLF4J及其下那些实现的外观......或更直接地桥接到管理员的首选位置。
对于应用程序开发人员来说,这真的无关紧要,只要最终管理员选择了一个日志记录工具,并且所有组件都可以注销它。如果该设施可以通过SLF4J和Log4J2-the-API接受消息,那就太好了。Log4J2-the-implementation就是这样做的。您也可以吃掉自己的蛋糕:您的应用程序可以享受Log4J2-the-API提供的机会,同时仍然使用SLF4J充分满足的库。如果管理员蔑视Log4J2-the-实现(尽管很难看出为什么他们会从任何角度),那么他们可以使用任何已经支持SLF4J的东西,而无需等待该日志记录实现支持Log4J2-the-API。你可以吃你的蛋糕,然后吃它。
对于库开发人员来说,这更像是一个问题。安全路径是SLF4J,因为它被广泛采用。如果日志记录对库的成功至关重要...特别是如果它是多线程的,日志语句的生成成本可能很高,如果它们最终不会被消耗,最好省略处理,如果有大量日志语句需要处理,性能至关重要,并且您的用户可能会欣赏Log4J2实现的好处,那么做Log4J2。但是,您也不会通过留在SLF4J来窃取用户的机会。如果管理员愿意,他们仍然可以使用Log4J-the-implmenation。
底线
如果您想要Log4J2提供的功能,那么请选择它们。如果您不需要它们,SLF4J是一个成熟,稳定的界面,具有很多支持。SLF4J仍然是开源基础设施的重要组成部分。Ceki为社区提供了很好的服务,作为回报,很多抱怨。
但是,由称职的实现支持的丰富 API 最终占了上风。今天的稳定就是明天的停滞。精益求精的过程还在继续。无需下车,只要它要去你想去的地方。