目的是系统异常出现时,开发马上能收到异常消息
传统查询异常方式
1.客户提出系统问题,最后消息流转到负责该系统的开发工程师这边;
2.开发工程师打开远程服务器,找到对应项目日志文件,查找日志识别异常,判断时间点和客户操作的时间点是不是一致,如果是分布式部署,还得查找另外的服务器日志,吐血了吧;那有同学会说,咋们公司上了ELK日志监控查询系统,直接在日志系统查询就可以了,大量日志堆扎,查起来还是不够方便。
进入这篇的主题,如何实现异常出现时,及时发出消息通知
使用spring的切面Aspect @AfterThrowing注解,破获抛出的异常,发出通知;下面上代码
《引入的包省略…》
/**
* 说明:
* 异常捕获切面
* @author wxq
**/
@Aspect
@Component
public class ExceptionLogAspect {
Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
//private RobotMsgService robotMsgService;//这里按需引入自己的业务处理类-todo
/**
* 切点:controller和service
* 需要修改对应的路径-todo
*/
@Pointcut("execution(* *.*.*.controller..*.*(..)) || execution(public * xxx.xxx.xxx.service..*.*(..)))")
public void pointCutService(){}
/**
* 前置通知(方法调用前调用)
* @param joinPoint
*/
@Before("pointCutService()")
public void doBeforeAdvice(JoinPoint joinPoint) {
}
/**
* 异常通知
* @param joinPoint
* @param exception
*/
@AfterThrowing(value = "pointCutService()", throwing = "exception")
public void doAfterThrowingAdvice(JoinPoint joinPoint, Throwable exception) {
try {
Signature signature = joinPoint.getSignature();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String uri = request.getRequestURL().toString();
String className = signature.getDeclaringTypeName();
StringBuffer sb = new StringBuffer();
sb.append("路径: ").append(uri).append(";\n");
sb.append("类: ").append(className).append(";\n");
sb.append("方法: ").append(signature.getName()).append(";\n");
sb.append("异常: ").append(exception.toString()).append("\n");
sb.append("详情: ").append(traceToString(exception));
logger.error("切面捕获抛出的异常,类名:【{}】-方法名:【{}】,异常:【{}】", signature.getDeclaringTypeName(), signature.getName(), exception.getLocalizedMessage());
//以下按需修改-todo
//robotMsgService.sendMsgToDding(sb.toString());
} catch (Exception ex) {
logger.error("切面捕获抛出的异常失败,{}", ex);
}
}
//截取异常堆栈信息--可以从这里快速判断问题出现在哪行代码
private String traceToString(Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw, true));
String result = sw.getBuffer().toString();
if (result.length() > 400) {
result = result.substring(0, 400) + ".....";
}
return result;
}
}