在Log4j2中更好地执行非日志记录器调用

使用Log4j 1.x并希望避免在某些情况下可能会造成额外的性能影响(即使实际上未记录该消息)时,通常使用日志记录防护 。 Java的简单日志记录外观 ( SLF4J )带给Java日志记录的最吸引人的功能之一是能够减少需要进行这些日志级别检查的情况的数量 。 在本文中,我将探讨如何使用Log4j 2.x的日志记录API更改来实现类似的好处。

下一个代码清单演示了记录长时间运行的操作。 第一个示例在名称为“ slow”的实例上隐式调用toString()方法。 第二个日志记录示例调用了一个长时间运行的方法。

传统,无人值守的日志记录

// Will implicitly invoke slow's 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 2(2.4)提供了多种方法来避免在未实际记录消息时对日志语句的性能造成影响。

  1. 可以重写日志语句,以便根本不记录昂贵的方法(包括昂贵的toString()调用)。
  2. 日志保护措施可用于确保仅在实际记录消息时才执行log语句的长时间运行的方法调用。
  3. 除非确实记录了消息,否则可以使用Log4j 2的参数化(格式化)记录器API来消除对隐式toString()方法的调用。
  4. 除非确实记录了消息,否则Log4j 2.4的lambda表达式记录器API可用于消除对记录的消息所需的任何操作(隐式或显式)的调用。

翻译自: https://www.javacodegeeks.com/2015/10/better-performing-non-logging-logger-calls-in-log4j2.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/358051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javaScript学习笔记之运算符

运算符 = 用于赋值。用于给 JavaScript 变量赋值。 运算符 + 用于加值。算术运算符 + 用于把值加起来。 下面展示了算术运算符及赋值运算符: <!DOCTYPE html> <html><head><meta charset="utf-8" /><title>孙叫兽测试运算符</…

编写高质量代码-OC 第7章 设计模式与Cocoa编程

45、设计模式是特定环境下的特定问题的解决方案46、MVC模式是一种复合或聚合模式47、对象建模在数据库中也广泛使用48、类簇可简化框架的公开架构而又不减少功能的丰富性 1、类簇基于抽象工厂设计模式2、类簇&#xff0c;可以用于隐藏实现的详细细节&#xff0c;为调用者提供一…

Goby反制复现

0x00 前言 最近复现Goby反制的时候遇到很多坑&#xff0c;记录一下反制过程以及遇到的坑点&#xff0c;还有世界上最强的黑客mux1ng帮我解决了很多问题。 0x01环境 攻击机&#xff1a; windows10 Goby1.8.230 172.20.10.3反制机&#xff1a; Windows7 Phpstudy2016 172.20.…

测试双重图案

前段时间&#xff0c;我写了一篇有关使用Test Double的后果的文章&#xff0c;但是与Test Double Patterns无关&#xff0c;仅是一个简单的清单。 今天&#xff0c;我想对其进行更改&#xff0c;并解释这些模式之间的差异。 正如我在提到的文章中写道&#xff1a; Test Doubl…

javaScript学习笔记之比较运算符||逻辑运算符||条件运算符(三目运算符)

比较运算符在逻辑语句中使用,以测定变量或值是否相等。 逻辑运算符用于测定变量或值之间的逻辑。 javaScript基于某些条件对变量进行赋值的条件运算符(三目运算符)。 HTML: <!DOCTYPE html> <html> <head><meta charset="utf-8"><title…

类的依赖注入

http://www.360doc.com/content/14/0421/09/10504424_370757998.shtml转载于:https://www.cnblogs.com/changbaishan/p/4949225.html

JDK 9:模块系统状态的重点

马克雷因霍尔德 &#xff08; Mark Reinhold &#xff09;的“模块系统状态 &#xff08;SOMS&#xff09;”已于本月初发布&#xff0c;它提供了信息丰富的可读性“对项目Jigsaw中原型的Java SE平台进行了增强的非正式概述&#xff0c;并被提议作为JSR 376的起点。” 在这篇文…

fckeditor漏洞_三十,文件上传漏洞、编辑器漏洞和IIS高版本漏洞及防御

一.编辑器漏洞 1.编辑器 编辑器属于第三方软件&#xff0c;它的作用是方便网站管理员上传或编辑网站上的内容&#xff0c;类似我们电脑上的Word文档。 编辑器通常分为两种情况&#xff1a; (1) 不需要后台验证&#xff0c;可以直接在前台访问且操作。通过方法找到编辑器&#x…

java学习笔记之条件语句(if...else)

条件语句用于基于不同的条件来执行不同的动作。 通常在写代码时,您总是需要为不同的决定来执行不同的动作。您可以在代码中使用条件语句来完成该任务。 在 JavaScript 中,我们可使用以下条件语句: if 语句 - 只有当指定条件为 true 时,使用该语句来执行代码if...else 语句 …

iOS 学习之NSPredicate

电话号码验证表达式 (BOOL)validateMobile:(NSString *)mobileNum { /** * 手机号码 * 移动&#xff1a;134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188 * 联通&#xff1a;130,131,132,152,155,156,185,186 * 电信&#xff1a;133,1349,153,180,189 */ NSStr…

javaScript学习笔记之break 和 continue 语句对比

break 语句用于跳出循环。 continue 用于跳过循环中的一个迭代。 break 语句可用于跳出循环。 break 语句跳出循环后,会继续执行该循环之后的代码(如果有的话): continue 语句中断循环中的迭代,如果出现了指定的条件,然后继续循环中的下一个迭代。 代码: <!DOCTYPE …

畅捷通T+任意文件上传(CNVD-2022-60632 )漏洞复现

一、漏洞描述 2022年8月29日和8月30日&#xff0c;畅捷通公司紧急发布安全补丁修复了畅捷通T软件任意文件上传漏洞。未经身份认证的攻击者利用该漏洞&#xff0c;通过绕过系统鉴权&#xff0c;在特定配置环境下实现任意文件的上传&#xff0c;从而执行任意代码&#xff0c;获得…

Spring 3使用JUnit 4进行测试– ContextConfiguration和AbstractTransactionalJUnit4SpringContextTests...

在Internet上寻找一种测试我的Spring 3应用程序的方法&#xff0c;我找到了许多描述如何使用JUnit测试应用程序的文章。 它们中的大多数都是不完整的示例&#xff0c;实际上并不起作用。 在这篇文章中&#xff0c;我将尝试填补这一空白&#xff0c;并撰写一篇简洁而简单的文章&…

RecyclerView滑动到底部自动加载

你经常听到“上拉加载”这样的字眼吗&#xff1f;你知道这个功能是怎么实现的吗&#xff1f;这篇文章记录了我对“上拉加载”的实现&#xff0c;与大家一起分享。 “上拉加载”针对的是RecyclerView或者Listview这样的列表控件&#xff08;本文以RecyclerView为例&#xff09;&…

javaScript学习笔记之typeof, null, 和 undefined之间的对比

typeof 操作符 你可以使用 typeof 操作符来检测变量的数据类型。 null 在 JavaScript 中 null 表示 "什么都没有"。 null是一个只有一个值的特殊类型。表示一个空对象引用。 undefined 在 JavaScript 中, undefined 是一个没有设置值的变量。 typeof 一个没有值的变量…

不喜欢节流吗?

您别无选择–基础系统&#xff08;此处的JVM将为您完成此选择&#xff09;。 我仍然记得2013年夏天&#xff0c;当时我正在运行一个项目&#xff0c;整个应用程序中只有1个URL使服务器瘫痪。 问题很简单-机器人决定以很高的速率索引我们的网站&#xff0c;并且该机器人正在创建…

OData V4 系列 查询操作

OData 学习目录 对OData的操作&#xff0c;主要是查询&#xff0c;下面把相关的查询情况列出来&#xff0c;供参考学习&#xff0c;每个操作都有对应的截图&#xff0c;便于理解 默认查询 $expand 查询导航属性关系 &#xff0c;查询Product相关的Supplier $top、$skip、$orde…

JSP项目打开不通的查看详情页动画是放大状态的解决办法

背景:前段时间做了一个详情页在当前页面的放大缩小的动画效果,——>我是如何用Jquery实现网页缩小放大的 今天测试反馈:详情页是缩小状态,点击关闭后打开其他的查看详情页页面,还是默认的缩小状态,需要做成,每次打开默认是放大的效果。 截图: 这个系统比较老,boots…

CentOS7--yum安装

1、创建yum文件夹 [roottester ~]# cd /usr/local/ [roottester local]# ls aegis bin etc games include lib lib64 libexec sbin share src [roottester local]# mkdir ./yum [roottester local]# cd yum2、下载yum源文件 http://mirrors.163.com/centos/7/os/x86…

单点登陆的三种实现方式

背景:单点登录(Single Sign On, SSO)是指在同一帐号平台下的多个应用系统中,用户只需登录一次,即可访问所有相互信任的应用系统。举例来说,百度贴吧和百度地图是百度公司旗下的两个不同的应用系统,如果用户在百度贴吧登录过之后,当他访问百度地图时无需再次登录,那么就…