java系统中拦截fatal/error异常并通知钉钉或邮件,核心是统一异常捕获、分级过滤与异步通知,可通过logback/log4j2自定义appender+filter、@controlleradvice全局处理器或aop切面实现,配合缓存去重、超时降级与安全签名确保高可用。

Java系统中拦截特定 Fatal/Error 级别异常 并触发钉钉或邮件通知,核心在于**统一异常捕获 + 分级过滤 + 异步通知**。不建议在每个 try-catch 中硬编码发送逻辑,而应通过全局异常处理器、日志框架(如 Logback/Log4j2)的扩展能力或 AOP 实现集中管控。
使用日志框架拦截 ERROR/FATAL 日志事件
Logback 和 Log4j2 都支持自定义 Appender 或 Filter,可在日志写入前判断级别和内容,精准拦截指定异常。
- 配置 Logback 的
AsyncAppender+ 自定义Filter,只放行ERROR或FATAL级别且满足条件的日志事件(如包含特定类名、异常类型或关键词) - 在自定义 Appender 中解析
ILoggingEvent,提取异常堆栈,匹配目标异常(如NullPointerException、SQLException或自定义的SystemFatalException) - 匹配成功后,调用封装好的钉钉 Webhook 发送接口(推荐异步线程池执行,避免阻塞日志线程)
基于 Spring Boot 全局异常处理器拦截未捕获异常
对未被业务 catch 的顶层异常(如 Controller 层抛出的 RuntimeException),可通过 @ControllerAdvice 统一处理。
- 定义
@ExceptionHandler(Exception.class)方法,但需结合Thread.currentThread().getStackTrace()或logger.error("msg", e)判断是否为真正致命错误 - 排除已知可恢复异常(如参数校验失败、业务码返回),仅对
e instanceof Error或e.getClass().getSimpleName().contains("Fatal")等规则触发告警 - 发送钉钉消息时,携带关键信息:服务名、主机 IP、时间戳、异常类名、简要堆栈(截取前 5 行)、traceId(如有)
用 AOP 拦截特定方法的致命异常
对关键路径(如支付回调、定时任务、核心 RPC 调用),可用 @Around 切面 主动捕获并决策是否告警。
- 定义切点表达式,例如
@Pointcut("@annotation(org.springframework.scheduling.annotation.Scheduled)")或指定包路径下的 service 方法 - 在环绕通知中 try-catch,若捕获到
Throwable,再按异常类型、消息内容、重试次数(如第 3 次失败才告警)等条件过滤 - 避免重复告警:可用本地缓存(如
ConcurrentHashMap<string long></string>)记录最近 5 分钟内同类异常的告警时间,相同异常类+方法签名 10 分钟内只发一次
钉钉/邮件通知的轻量集成要点
通知模块要解耦、异步、带降级,不能因网络问题拖慢主流程。
- 钉钉推荐使用 Webhook + 签名验证(加 timestamp + sign),避免 token 泄露;消息体用 Markdown 格式,突出异常等级和关键字段
- 邮件建议走企业内部 SMTP(如腾讯企业邮),主题加 [ALERT][PROD] 前缀,正文含链接跳转到日志平台(如 ELK)对应 traceId
- 务必设置超时(HTTP connect/read timeout ≤ 2s)和 fallback:发送失败时写入本地告警队列文件,由后台脚本补发
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











