Java 中, logback 和 log4j2 日志工具,不使用 log.isDebugEnabled 判断就直接调用 debug 进行日志,在日志级别没有到 debug 的情况下,到底带来什么损失呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
BraveXaiver
V2EX    Java

Java 中, logback 和 log4j2 日志工具,不使用 log.isDebugEnabled 判断就直接调用 debug 进行日志,在日志级别没有到 debug 的情况下,到底带来什么损失呢?

  •  
  •   BraveXaiver 2023-10-22 21:06:05 +08:00 2748 次点击
    这是一个创建于 718 天前的主题,其中的信息可能已经有所发展或是发生改变。
    不加这个东西,我写着爽不说,代码整体看起来也更加美观。不知道大家是不是持相同看法。

    所以我是真的很想不写,但又不知道这个到底为什么是约定俗成的最佳范式。

    感谢任何分享和解答!
    第 1 条附言    2023-10-22 22:06:24 +08:00
    谢谢,主要就是字符串格式化时,担心 toString 大 POJO 时带来的性能开销。但是即便以 jdk8 这样的老 JVM ,不要说 toString ,就算是调用 jackson 处理 1MB 不到的请求体,也是几乎不用担心性能开销的吧(若无高并发)。

    换言之,如果确定程序中能遇到的 POJO json 化后最多也就 10-20 kb, debugEnabled 不查也没问题。
    16 条回复    2023-10-23 16:03:58 +08:00
    NotFoundEgg
        1
    NotFoundEgg  
       2023-10-22 21:11:55 +08:00   1
    即使不打印日志,但如果涉及到字符串拼接或 toString 也会损耗性能,所有要不就判断,要不就占位符,不要使用“+”的方式拼接

    不过实际写的时候我个人也很少在意这个
    clickhouse
        2
    clickhouse  
       2023-10-22 21:13:22 +08:00   1
    很简单,比如你 debug 打印一个对象的具体内容,不管你事 toString 也好,还是转 JSON 打印也好,这个方法都会被执行。而你不是 debug 级别,那么这个方法就白白消耗了系统的资源。
    wdlth
        3
    wdlth  
       2023-10-22 21:17:31 +08:00   1
    因为用占位符的话,后续的参数还是需要经过执行的,不过大多时候参数是已经确定的值/引用,性能开销没这么大。
    如果日志占位参数是较复杂的方法,加上 isDebugEnabled 跳过更好。
    stinkytofu
        4
    stinkytofu  
       2023-10-22 21:21:10 +08:00
    @clickhouse #2 所以说 C/C++中的预编译的机制真的挺好的
    vitoliu
        5
    vitoliu  
       2023-10-22 21:44:47 +08:00
    目光向前看,debug 和 trace 日志都没有意义了。
    因为已经有了 arthas 。
    就像 Spring 之前 xml 、tomcat web.xml 配置也有一堆范式一样,现在谁还用啊?
    BraveXaiver
        6
    BraveXaiver  
    OP
       2023-10-22 22:06:17 +08:00
    @NotFoundEgg
    @clickhouse
    @wdlth

    谢谢,主要就是字符串格式化时,担心 toString 大 POJO 时带来的性能开销。但是即便以 jdk8 这样的老 JVM ,不要说 toString ,就算是调用 jackson 处理 1MB 不到的请求体,也是几乎不用担心性能开销的吧(若无高并发)。

    换言之,如果确定程序中能遇到的 POJO json 化后最多也就 10-20 kb, debugEnabled 不查也没问题。
    BBCCBB
        7
    BBCCBB  
       2023-10-22 22:57:51 +08:00
    方法调用要资源+时间.. 如果你 log.debug 的参数里有需要计算得到的结果, 那也要浪费资源..

    比如
    log.debug("{}", computeXXX());

    这个 computeXXX()需要耗费很多资源..
    BBCCBB
        8
    BBCCBB  
       2023-10-22 22:59:33 +08:00   1
    10-20kb json 字符串已经是很大的开销了..

    要养成好习惯. debug log 里有较大消耗, 比如非 xxx.getXX() 简单获取属性的操作, 都加上 log.isDebugEnable
    zsdroid
        9
    zsdroid  
       2023-10-23 09:05:40 +08:00
    这简单,自己用 lambda 封装一下就解决这个问题了。
    cloud107202
        10
    cloud107202  
       2023-10-23 09:26:19 +08:00
    不加判断会带来额外的 Call by Value Evaluation 开销


    高版本 slf4j 2.X ( spring boot3 的自动依赖) 有个 Fluent Logging API 能优雅解决这个问题(和因为强迫症希望少一组 if-block 引发心里不适的问题)
    itechify
        11
    itechify  
    PRO
       2023-10-23 09:26:48 +08:00 via Android
    用对象包一层,tostring 在将源对象输出
    aqua02
        12
    aqua02  
       2023-10-23 11:00:54 +08:00 via Android
    按计算机原理的角度来说,一个主频为 1ghz 执行一个机器指令 时间为 1/1g 秒, 又因为它是函数 那就加几个指令 当 4 条吧,又因为它是 java 封装 ,总指令数 x5 吧,时间就是 ( 4+1 )*5 / 1g 秒,忽略不计吧,1g=10^9 。 具体几条可以反编译看看。
    Masoud2023
        13
    Masoud2023  
       2023-10-23 13:39:05 +08:00
    不是我非在这抬杠,一大堆第三方库开源组件也没非得在 log.debug 前面判断环境吧。

    都考虑到这种性能损耗了,为什么不换其他的编译语言?

    觉得不爽可以自己给 java 写个 babel ,打包的时候把 log.debug 全删了。

    或者直接换个语言。
    Aresxue
        14
    Aresxue  
       2023-10-23 14:04:33 +08:00
    如果参数是已经计算好的变量判断不判断其实都还好,如果占位符的参数还涉及到比较吃 cpu 的计算最好还是判断下能节省点 cpu 。
    oldshensheep
        15
    oldshensheep  
       2023-10-23 16:02:16 +08:00   1
    如果你看 log4j2 源码会发现实际上 log4j2 已经自动检查 log level 了,不会做无谓的调用。但是如果你手动拼接字符串 "log some %s some".formated(obj),这个损耗会大一些,因为会调用 obj.toString 。调用这样的 log 方法 (final String message, final Object... params),而不是手动拼接字符串。

    还有一直情况就是做大量计算,这种情况可以使用,lambda ,()-> computeSome() 这种也是一样会检查后再调用
    cnzjl
        16
    cnzjl  
       2023-10-23 16:03:58 +08:00
    突然想到写一个编译插件,打包项目的时候判断下 log.debug()有没有被 if(log.isDebugEnable)包裹,没有的话就加上[绿帽 doge]
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3101 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 21ms UTC 11:06 PVG 19:06 LAX 04:06 JFK 07:06
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86