【问题标题】:logger usage, is parameterization better or using + to add arguments?记录器的用法,参数化更好还是使用 + 添加参数?
【发布时间】:2016-08-24 04:05:24
【问题描述】:

以下哪项是记录器的更好用法?

  1. 参数化(log4j 2)

    logger.info("User {} has logged in using id {}", map.get("Name"), user.getId());`
    
  2. 使用 + 运算符 (log4j)

    logger.info("User"+ map.get("Name") +" has logged in using id " +user.getId());`
    

为什么?

【问题讨论】:

  • 为什么?我想知道当我们参数化时会发生什么。我似乎没有找到参数化的代码。此外,如果对于 log4j logger.info 只允许对象和可抛出。不是多个参数。
  • 好吧,不要使用像 log4j 这样的古老日志框架,而是使用更好的框架(或者最好是像 SLF4J 这样的日志外观)。
  • 是的.. 我正在编辑别人的代码。他们已经有了 log4j。我会改变它。谢谢。我知道参数化更好,但不知道原因。你的回答说明了这一点。谢谢@kayaman :)

标签: java apache log4j log4j2


【解决方案1】:

即使没有别的,使用+ 时发生的额外StringBuilder shenanigans 也会使使用参数成为显而易见的选择。

更不用说在连接值时,即使未启用日志记录级别,也会调用所有参数的toString()方法,这意味着您正在浪费CPU来构建一个永远不会被记录的字符串. 如果有很多 debug() 语句,这将产生(尽管很小)影响,而 DEBUG 级别通常在生产环境中被禁用。

【讨论】:

  • 从 2021 年的角度来看,第一个替代方案会阻止 Log4j 扩展用户提供的查找(参见CVE-2021-44228)。
  • @PiotrP.Karwasz 实际上即使是参数化版本也容易受到影响,这就是它如此危险的原因。
【解决方案2】:

Parameterized messages 避免格式化文本,直到 Log4j 确定消息将被记录。这使您可以避免使用if (logger.isDebugEnabled())... 之类的检查来包围 logger.debug(...) 调用,从而提供更简洁的代码。

这个答案基于现代日志框架,而不是像 Log4J 这样过时的框架。

当您说“过时”时,您一定是在谈论 Log4j 1.x。截至 2014 年,Log4j 2 是最前沿的开源日志框架。它借鉴了 SLF4J 的一些想法,例如 parameterized log messages,但添加了一个插件系统,因此您可以轻松添加 custom appenders、自定义布局和 custom lookups。此外,Log4j 2 支持custom log levelslambda expressions 和无锁且非常高效的Async Loggers。为了增添趣味,从 2.6 版开始,Log4j 2 是garbage-free

Kayaman 可能在谈论 Log4j 1,自 2015 年 8 月以来一直是 End of Life

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-09
    • 1970-01-01
    • 1970-01-01
    • 2022-08-12
    • 2012-04-23
    • 2014-10-17
    • 1970-01-01
    相关资源
    最近更新 更多