惰性日志

点击上方“朱小厮的博客”,选择“设为星标

做积极的人,而不是积极废人


640

来源:itnext.io/lazy-logging-40314cf9bb25


在代码中添加日志时要当心:有时尽管并没有记录日志,也会执行日志语句。例如下面的代码:


```javalog.debug("I found {} and {}", getone(), gettwo());```


看起来很好,似乎没有任何问题。日志输出字符串中包含了两个调试参数。


所以一切正常,没有问题?也不尽然。


在记录日志的代码中可以看到下面两个输入:


  •  `getone()`

  •  `gettwo()`


这两个方法会"一直"调用。这意味着,即使实际可能不会执行 `log` 语句,仍然会计算所有 `log` 方法传入的参数。


如果这些调用开销很大,那么可能会浪费大量 CPU 资源。


一种典型的解决方案像下面这样:


```javaif (log.isDebugEnabled()) {    log.debug("I found {} and {}", getone(), gettwo());}```


但这种方法相当丑陋:这不正是 `log.debug` 完成的功能吗?只在启用调试时才记录日志。


我们需要的是一个单行调试语句,只在启用日志记录时计算输入的参数。


为了解决类似的情况,我们将应用 Java 8 Supplier 模式,只在需要的时候执行计算。


不幸的是,大多数日志框架并不支持 Supplier 模式。


至少是直接支持。


实际上,`logger` 并不期望输入的参数一定是字符串,实际参数可以是任意对象。`logger` 会调用对象的 `toString` 方法把它转换为字符串。这里的诀窍是`logger` 只在日志启用的情况下调用字符串。


因此,要实现惰性日志只需要用一个对象来包装 Supplier,该对象仅在调用 toString 时调用 Supplier。


```javaimport java.util.function.Supplier;public class LazyString {    private final Supplier<?> stringSupplier;        public static LazyString lazy(Supplier<?> stringSupplier) {        return new LazyString(stringSupplier);    }    public LazyString(final Supplier<?> stringSupplier) {        this.stringSupplier = stringSupplier;    }    @Override    public String toString(){        return String.valueOf(stringSupplier.get());    }}```


现在可以更新之前的日志代码,结果如下:


```javaimport static LazyString.lazy;log.debug("I found {} and {}", lazy(this::getone), lazy(this::gettwo));```


理想情况下,日志框架能直接支持 Supplier。但在等待的过程中,这也是一种变通的办法。


完整示例代码,请查看我的 Github 仓库:<https://github.com/efenglu/lazyLogger>


想知道更多?描下面的二维码关注我

640?wx_fmt=png

好文推荐:


>>>Learn More<<


喜欢就点个"在看"呗^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值