网站设计注意事项,网站动态与静态,百度移动端模拟点击排名,腾讯会议开始收费使用Log4j 1.x并希望避免在某些情况下可能会造成额外的性能影响#xff08;即使实际上未记录该消息#xff09;时#xff0c;通常使用日志记录防护 。 Java的简单日志记录外观 #xff08; SLF4J #xff09;带给Java日志记录的最吸引人的功能之一是能够减少需要进行这些日… 使用Log4j 1.x并希望避免在某些情况下可能会造成额外的性能影响即使实际上未记录该消息时通常使用日志记录防护 。 Java的简单日志记录外观 SLF4J 带给Java日志记录的最吸引人的功能之一是能够减少需要进行这些日志级别检查的情况的数量 。 在本文中我将探讨如何使用Log4j 2.x的日志记录API更改来实现类似的好处。 下一个代码清单演示了记录长时间运行的操作。 第一个示例在名称为“ slow”的实例上隐式调用toString()方法。 第二个日志记录示例调用了一个长时间运行的方法。 传统无人值守的日志记录 // Will implicitly invoke slows toString() method
logger.debug(NORMAL: slow);
// Will explicitly invoke the long-running method expensiveOperation()
logger.debug(expensiveOperation()); 在前面的示例中即使实际上未执行任何日志记录这两个日志记录操作也将花费很长时间。 先前代码清单中的日志记录语句仅在日志记录级别为DEBUG或不太明确的日志级别例如TRACE时才实际记录但是即使不进行任何记录它们的昂贵操作也将运行。 在Log4j 1.x中有两种方法可以解决此问题。 一种方法通常是最好的方法是尝试重新编写log语句以便不涉及长时间运行的操作 。 如果这不切实际例如当需要与长时间运行的操作相关联的上下文以使日志消息有用时则可以使用日志保护。 接下来演示在Log4j 1.x中有效的方法。 传统的受保护的日志记录 if (logger.isDebugEnabled())
{logger.debug(GUARDED: slow);logger.debug(expensiveOperation());
} 如前面的代码清单所示日志防护措施可以有效地防止调用长时间运行的操作即使无论如何也不会记录任何消息。 但是使用日志保护确实会带来一些缺点。 也许最主要的缺点是引入了额外的有些人会说是肿的代码。 另一个潜在的缺点很少见但更为严重由于条件块和关联块引入了额外的作用域因此它更容易在条件块中引入错误代码甚至有可能在依赖于日志记录级别的情况下带来副作用代码块。 最常见的情况之一是日志调用实际上不会记录任何内容但会显着影响性能这是当将对象传递给logger调用或与传递给该字符串的字符串连接时显式或隐式调用对象的toString方法。记录器调用。 在上面的两个代码清单中通过将字符串文字“ GUARDED”与名为“ slow”的变量的隐式调用toString()方法进行连接将该字符串传递给logger调用从而证明了这种情况。 SLF4J 普及了参数化日志记录调用的概念Log4j 2在其日志记录API中提供了类似的支持 。 下面的代码演示了如何使用它。 参数化记录 logger.debug(PARAMETERIZED: {}, slow);
logger.debug({}, expensiveOperation()); 当使用比DEBUG更特定的日志级别执行上述参数化日志记录示例时由于进行了参数化日志记录因此将不会尝试在“ slow”变量上使用隐式toString() 。 但是参数化日志记录无法帮助其他日志记录情况因为尽管进行了参数化日志记录但仍将调用方法expensiveOperation() 。 还要注意虽然参数化日志记录在隐式toString()调用的情况下有所帮助 但在显式toString()调用中却无济于事 。 即使日志记录级别比DEBUG更具体在logger语句中对slow.toString()的调用仍会导致性能slow.toString() 。 Log4j 2.4引入了一种基于Lambda的机制 该机制可用于延迟对传递给logger调用的方法的调用这样如果该语句的记录级别低于当前日志级别则根本不需要执行它们。 。 这表现在下一代码列表其中toString()方法被明确地通过λ表达式称为“慢”变量的对象上并且expensiveOperation方法是通过调用方法的参考 。 Lambda表达式记录 logger.debug(LAMBDA: , () - slow.toString());
logger.debug({}, this::expensiveOperation); 当上述代码的日志级别设置为比DEBUG更特定的级别时由于基于lambda表达式的延迟加载因此不会调用“慢”对象的toString()方法和expensiveOperation方法。 换句话说类似于该示例与警卫一起使用的方式使用lambda表达式可以防止不必要地执行可能长时间运行的方法除非要真正记录它们的结果。 此lambda表达式支持已在2.4版中添加到Log4j并且当然需要Java 8 。 摘要 Log4j 22.4提供了多种方法来避免在未实际记录消息时对日志语句的性能造成影响。 可以重写日志语句以便根本不记录昂贵的方法包括昂贵的toString()调用。 日志保护措施可用于确保仅在实际记录消息时才执行log语句的长时间运行的方法调用。 除非确实记录了消息否则可以使用Log4j 2的参数化格式化记录器API来消除对隐式toString()方法的调用。 除非确实记录了消息否则Log4j 2.4的lambda表达式记录器API可用于消除对记录的消息所需的任何操作隐式或显式的调用。 翻译自: https://www.javacodegeeks.com/2015/10/better-performing-non-logging-logger-calls-in-log4j2.html