作为javaer都知道spring相关项目大部分情况下都会通过全局捕获异常,并将其包装为更人性化地提示给前端。并且在捕获异常后一般也都会记录到日志里(异常的调用堆栈信息),方便开发排查问题。
这里有个比较明显的问题就是系统中通常会有比较多的业务异常,即如用户不存在,状态不对等等业务异常,如果也记录全部异常堆栈信息,那么个人就觉得有点浪费磁盘空间,且底层框架的堆栈信息对排查问题没有多大指导性意义。如下图(图范围有限,底下还有许多堆栈信息):
遂经过调整优化后的spring全局异常处理器之处理业务异常
@ExceptionHandler(BizRuntimeException.class)
public Result<?> handleBusinessRuntimeException(BizRuntimeException e) {
// 只记录与本系统相关的类调用堆栈信息,即只有以mayfly.开头的包名下的类才会记录到日志中
LOG.error("业务异常:{}", ThrowableUtils.getStackTraceByPn(e, "mayfly."));
return Result.error(e.getErrorCode(), e.getMessage());
}
ThrowableUtils类,参考Throwable#printStackTrace
方法
/**
* 获取以指定包名为前缀的堆栈信息
*
* @param e 异常
* @param packagePrefix 包前缀
* @return 堆栈信息
*/
public static String getStackTraceByPn(Throwable e, String packagePrefix) {
StringBuilder s = new StringBuilder("\n").append(e);
for (StackTraceElement traceElement : e.getStackTrace()) {
if (!traceElement.getClassName().startsWith(packagePrefix)) {
break;
}
s.append("\n\tat ").append(traceElement);
}
return s.toString();
}
调整后日志信息
经过调整优化后的处理,记录业务异常时只会记录本系统包相关的类调用堆栈信息。去除底层框架spring等的调用堆栈,减少日志磁盘空间,且对排查业务异常问题更加简洁明了。具体更多细节可参考 https://gitee.com/objs/mayfly