Java中打印日志的坑(不打印堆栈信息)

本文揭示了在日志记录中忽略堆栈信息可能导致的问题,强调了堆栈信息在错误排查中的关键作用。常见的错误做法包括仅使用异常消息或toString(),而正确的做法是完整打印异常及参数信息。建议使用log.error加上异常对象e,确保堆栈跟踪的完整性。同时,提倡使用英文日志和避免中文逗号,以提高效率并防止乱码。
摘要由CSDN通过智能技术生成

背景

打印日志的大坑。很多同事不打印堆栈信息直接这么写

log.error("exception occur! param1:{},param2:{}", param1, param2);

log.error("exception occur! param1:{}", e.getMessage());

log.error("exception occur! param1:{}", e.toString());

这真的是个大坑,没有堆栈信息有时候很难排查问题。

首先 getMessage() 是异常的信息,只是很简短的信息,比如 /by zero 这个就是除零异常 getMessage() 得到的。

其次,e.toString() 会让人以为返回了完整的堆栈信息(以字串形式),但其实不是,返回的跟 getMessage() 几乎是一样的。

toString() 的源码

public String toString() {
    String s = getClass().getName();
    String message = getLocalizedMessage();
    return (message != null) ? (s + ": " + message) : s;
}

public String getLocalizedMessage() {
    return getMessage();
}

public String getMessage() {
    return detailMessage;
}

可以看到 getMessage()e.toString() 其实区别要么是完全一样,要么是前面加了个类名和冒号和空格(s + ": ")

解决

一定要杜绝上面的写法。虽然lombok的 @Slf4j 提供的log,其打印日志的方法比较蛋疼,如果要打印 异常e就没法使用占位符 {},但是我们可以使用拼接的方式,参数多的时候用String.format 也是可以的

正例

log.error("exception occur! tenantId:" + tenantId, e);
// 或者
log.error(String.format("exception occur! tenantId:%s",tenantId), e);

注意,使用 String.format() 的时候,如果占位符 %s 的数量和填充进去的参数的数量不一致会发生运行时异常,这个比较坑。

补充细节:

一定要注意,如果参数数量不一致,会有提醒的。如下的黄底提醒

在这里插入图片描述

如果用log,参数不匹配,也会有黄底警告:

在这里插入图片描述

补充

打印日志用英文,比较节省,另外也不怕乱码。注意别用了中文逗号!

我觉得可能 log 缺少一个方法,比如

log.info("abc,param1:{},param2:{}", e, param1, param2);

由于缺少这个方法,所以如果想要打印 异常e 的堆栈就得放弃使用 {} 这种占位符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值