【log4j】日志打印必须使用log.isDebugEnabled()?不使用会消耗系统资源?

作者在代码评审后研究Log4J日志打印源码。发现写法1在日志级别判断前就调用对象toString()方法拼接日志内容,会占用系统资源;写法2则在满足条件后才调用。总结指出,可通过规范日志输出格式,用{}占位符避免资源占用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前的一次代码评审,说代码中有问题,对于频发打印的日志,没有使用如下第二中方式,说是有问题,虽然日志没有打印,但是还是会调用demo.toString()方法,占用系统资源

// 方式一:
log.debug("xxxx:{}",demo)
// 方式二:
if(log.isDebugEnabled()){
	log.debug("xxxx:{}",demo)
}

说的我一脸蒙B,我之前也没看过具体源码,也貌似听过这个说法,加之是在很多源码里面看到各个大佬都是使用的这种写法。也没敢吭声。但调整了代码,闲来无事,总觉得吧还是要研究一下知其所以然,不然以后还得蒙B。

查看log4J日志打印源码

public void info(final String format, final Object o) {
	this.logger.logIfEnabled(FQCN, Level.INFO, (org.apache.logging.log4j.Marker)null, format, o);
}

 @Override
    public void logIfEnabled(final String fqcn, final Level level, final Marker marker, final String message,
            final Object p0) {
        if (isEnabled(level, marker, message, p0)) {
            logMessage(fqcn, level, marker, message, p0);
        }
    }

不看还好,看了感觉更加的蒙了,这个不是在框架中已经帮我们自行添加了logIfEnabled的判断了吗,如果不满足日志输出的条件,就不会调用logMessage方法进行字符的拼接。兜兜转转终于发现了大家所说的问题了。我们来看看如下两个日志输出的方式:

写法1:
log.info("ffffffffffffff:"+ demo);
写法2:
log.error("bbbbbbbbb:{}", demo);

问题就在这里,如果使用写法1,在进行日志级别的判断前,就会调用demo的string方法对需要打印的日志内容进行拼接组装,然后再进行日志级别的判断。这就出现了之前大家说了,虽然不满足日志输出级别的要求,但是还是调用了对象的toString()方法,占用了系统资源
如果我们使用写法2,则不存在这种问题,因为demo作为一个对象传入被调用的方法中,需要在isEnabled()方法调用后满足条件后,调用logMessage()时才会调用demo的toString()方法进行字符的拼接。

总结:

log日志的打印不是非要使用if(log.isDebugEnabled())的方式,来避免系统资源的占用。我们需要通过规范自己日志输出的格式。不要使用+进行字符串的拼接,而因使用{}占位符的形式,避免资源的占用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值