Java 是否值得将slf4j与log4j2一起使用
我无法决定是否对log4j2使用slf4j。根据在线帖子,它看起来不会对性能造成任何影响,但它确实是必需的 此外,这些点的规则有利于log4j2:Java 是否值得将slf4j与log4j2一起使用,java,logging,log4j,slf4j,log4j2,Java,Logging,Log4j,Slf4j,Log4j2,我无法决定是否对log4j2使用slf4j。根据在线帖子,它看起来不会对性能造成任何影响,但它确实是必需的 此外,这些点的规则有利于log4j2: SLF4J强制应用程序记录字符串。如果要记录文本,Log4j 2 API支持记录任何字符序列,但也支持按原样记录任何对象 Log4j 2 API支持记录消息对象、Java 8 lambda表达式和无垃圾日志记录(它避免在记录CharSequence对象时创建vararg数组和字符串) 继续:编程到log4j2api而不是slf4j 它是安全的:lo
- SLF4J强制应用程序记录字符串。如果要记录文本,Log4j 2 API支持记录任何字符序列,但也支持按原样记录任何对象
- Log4j 2 API支持记录消息对象、Java 8 lambda表达式和无垃圾日志记录(它避免在记录CharSequence对象时创建vararg数组和字符串)
继续:编程到log4j2api而不是slf4j 它是安全的:log4j2api提供了与slf4j完全相同的保证,甚至更多 既然Log4j2本身被分离为一个API和一个实现模块,那么使用SLF4J就没有任何价值了 是的,这是一个良好的工程实践,让您的选择保持开放。您可能希望稍后更改为另一个日志记录实现 在过去10年左右的时间里,在应用程序中构建这样的灵活性意味着使用像SLF4J这样的包装器API。但这种灵活性并非免费提供的:这种方法的缺点是应用程序无法使用底层日志库中更丰富的功能集 Log4j2提供了一种解决方案,它不需要将应用程序限制为最低公分母 安全阀:log4j-to-slf4j Log4j2包括一个
log4j-to-slf4j
桥接模块。任何根据log4j2api编码的应用程序都可以随时选择将支持实现切换到任何符合slf4j的实现
如问题中所述,与使用slf4j等包装器API相比,直接使用Log4j2 API提供了更多功能,并具有一些非功能性优势:
- 消息API
- Lambdas用于延迟日志记录
- 记录任何对象,而不仅仅是字符串
- 无垃圾:尽可能避免创建varargs或字符串
- CloseableThreadContext在您完成项目后自动从MDC中删除项目
披露:我对Log4j2有所贡献
更新:对log4j2api的编程以某种方式引入了“facadeforfacade”,这似乎有些混乱。log4j2api和SLF4J在这方面没有区别 当使用本机实现时,这两个API都需要2个依赖项,而非本机实现则需要4个依赖项。SLF4J和Log4j2 API在这方面是相同的。例如:
有很多因素使得日志记录“比乍看起来更复杂”(因此经历了几十年的艰苦战斗!) 关注点分离 在一天结束时,代码“发送日志数据”,而这些数据“在某处结束”。但它的最终去向取决于收集的目的。事实上,现代软件是由各种组件组成的,它们都可能需要日志记录,这使情况变得非常复杂
让我们考虑一个最坏的情况:所有的组件都使用<代码>系统。至少所有语句都是按执行顺序执行的,但要区分哪一个组件生成了每一条输出可能并不简单。而且,对于使用它们的上下文,某些组件可能过于冗长
让我们考虑下一个最坏的情况:所有组件都有自己的安排来控制它们的日志记录行为和目的地。管理员可能需要为一个软件配置几十个日志系统。现在,日志语句不在一起,它们的顺序也不正确。希望他们都有一个一致的时间戳策略
我们希望介于两者之间:代码可以说‘logthis’,管理员可以控制它的最终位置 过于简短的历史 进入log4jv1,它解决了“级别”、“附加器”、“过滤器”、“布局”和“上下文”等概念的问题。。。一个由分层“记录器名称空间”(包括一种自然利用Java包名称空间的方法)支持的概念体系结构,以及一种便于管理的配置机制 一切都很好。。。只要软件中的所有组件都依赖于同一版本!曾经有一段时间,这些事情在不断变化。SLF4J的主要贡献是从组件开发人员的角度将这些概念“强化”为一个稳定的API,而不影响管理员完成其部分工作的选择。库可以依赖于SLF4J的“facade”,期望它们只需在堆栈中调用几次就可以与“实现”对话。管理员可以选择适合他们的方式将日志组成他们关心的一致记录 (当您的软件在容器中运行时,情况就更复杂了,容器有自己的日志记录需求,而您甚至不是在容器中运行的同一个应用程序……Tomcat的JULI日志记录(用于自己的内部日志记录)对在类加载器子上下文中运行的应用程序“置之不理”。) Java社区进程神秘地蔑视了Log4J的工作,决定在Java.util.logging
中实现几乎相同的概念架构,在细节上可以说灵活性较低。然而,由于j.u.l
本质上是SLF4J语义丰富性的子集,因此很容易使SLF4J成为j.u.l
的门面
Apache的Commons-Util日志记录是probabl