如何排查catch块中自定义Log类的日志方法不当使用场景?
自定义Log类异常日志不当使用的排查与修复方案
问题背景
我曾尝试用正则解决这个问题,但效果不好。我们项目里有个自定义静态Log类,提供的日志方法如下:
public static void info(Object source, String message) public static void info(Object source, String message, Throwable t)
(其他级别如error方法签名一致)
实际使用中存在不少不当用法,导致日志缺失完整异常栈信息,调试困难:
错误示例
// 错误示例1:完全不传递异常 try { // 业务逻辑 } catch (Exception e) { Log.error(this, "oops"); } // 错误示例2:拼接异常toString,丢失栈信息 try { // 业务逻辑 } catch (Exception e) { Log.error(this, "oops " + e); } // 错误示例3:只传异常消息,丢失栈信息 try { // 业务逻辑 } catch (Exception e) { Log.error(this, "oops " + e.getMessage()); }
正确/合规示例
// 正确用法:直接传递异常参数 try { // 业务逻辑 } catch (Exception e) { Log.error(this, "oops", e); } // 正确:日志传异常后执行其他逻辑 try { // 业务逻辑 } catch (Exception e) { Log.error(this, "oops", e); Log.info(this, "also doing this other thing"); } // 技术合规但建议记录异常:catch的异常明确标记为ignored try { // 业务逻辑 } catch (Exception ignored) { Log.error(this, "oops"); } // 技术合规但建议优化:日志未传异常,但重抛时携带了原异常 try { // 业务逻辑 } catch (Exception e) { Log.error(this, "oops"); throw new OtherException(e); }
我的需求是:找出catch块中所有日志方法的不当使用场景——即异常既未作为日志方法的参数传入,也未作为重新抛出异常的原因。项目是大型老项目,直接重构Log类成本太高,优先考虑查找/替换方案,同时也接受其他可行方案。
注:依赖log4j、java.util.logging等框架的分析工具不适用,因为这是自定义静态Log类。
可行方案(基于IntelliJ IDEA)
1. 结构搜索(Structural Search)
正则无法精准识别代码语法结构,IntelliJ的结构搜索是更可靠的方案:
- 打开
Edit > Find > Search Structurally(快捷键Ctrl+Shift+S) - 点击
New Template,输入以下模板(针对单日志语句的catch块):try { $STATEMENTS$ } catch ($EXCEPTION_TYPE$ $EXCEPTION_VAR$) { Log.$LOG_LEVEL$($SOURCE$, $MESSAGE$); $OTHER_CODE$ } - 设置变量约束:
$LOG_LEVEL$:指定为error/info等你需要检查的日志级别$EXCEPTION_VAR$:类型约束为Throwable及其子类$OTHER_CODE$:添加约束不包含throw $NEW_EXC$($EXCEPTION_VAR$)或throw $NEW_EXC$(*, $EXCEPTION_VAR$)(即排除重抛时携带原异常的情况)- 额外排除
Log.$LOG_LEVEL$($SOURCE$, $MESSAGE$, $EXCEPTION_VAR$)这种正确调用的情况
运行搜索后,就能精准定位所有不符合要求的日志调用。
2. 自定义代码检查规则(Inspection)
如果需要长期监控这类问题,可以创建自定义Inspection:
- 打开
File > Settings > Editor > Inspections - 点击
+ > Custom Structural Search Inspection - 导入上面的结构搜索模板,设置检查提示信息(比如“未记录异常栈且未重抛原异常”)
- 应用设置后,运行
Analyze > Inspect Code,选择整个项目即可批量标记所有违规位置
3. 批量结构替换(针对简单场景)
对于大量重复的错误调用,可以用结构替换批量修复:
- 打开
Edit > Find > Replace in Path,切换到Structural Replace - 查找模板:
Log.error($SOURCE$, $MESSAGE$); - 替换模板:
Log.error($SOURCE$, $MESSAGE$, $E$); - 设置上下文约束为
catch ($E$) { ... },确保只替换catch块内的调用
注意:替换后需要人工核查(比如catch (Exception ignored)的场景可能不需要修改),避免误操作。
内容的提问来源于stack exchange,提问作者EarthTurtle
相关产品推荐
相关产品推荐

