Spring Boot中实现线上崩溃日志自动上报需组合@ControllerAdvice与JVM级Thread.setDefaultUncaughtExceptionHandler:前者处理Web层异常,后者兜底捕获线程池、定时任务等非Web异常;Sentry 6.x+默认集成未捕获异常处理器,Bugu则需手动注册,并均应增强上下文(如traceId、userId)且避免敏感信息泄露。

在 Java 应用(尤其是 Spring Boot)中,通过全局异常处理器结合 Sentry 或 Bugu 实现线上崩溃日志自动上报,核心是两步:统一捕获未处理异常 + 将异常信息结构化发送至监控平台。下面以实际可落地的方式说明关键配置和注意事项。
配置全局异常处理器并触发 Sentry/Bugu 上报
Spring Boot 推荐使用 @ControllerAdvice + @ExceptionHandler 捕获控制器层异常,但**这无法覆盖线程池、定时任务、异步方法、Filter 中抛出的异常**。真正兜底的是 JVM 级别的 Thread.setDefaultUncaughtExceptionHandler。
建议组合使用:
- 用
@ControllerAdvice处理 Web 层常见业务异常(如参数校验失败),按需决定是否上报 Sentry - 在应用启动时注册全局未捕获异常处理器,确保所有线程的致命崩溃(如
NullPointerException、OutOfMemoryError)都能被 Sentry 自动采集
示例(Sentry):
立即学习“Java免费学习笔记(深入)”;
Sentry SDK 6.x+ 默认已自动集成 JVM Uncaught Exception Handler,只需初始化即可:// ApplicationRunner 或 @PostConstruct 中
Sentry.init(options -> {
options.setDsn("https://xxx@o123456.ingest.sentry.io/123456");
options.setEnvironment("prod");
options.setRelease("myapp@1.2.3");
options.setTracesSampleRate(0.1); // 可选:开启性能监控
});
让 Sentry 捕获非 Web 线程中的异常(如定时任务、线程池)
Sentry 默认只监控主线程和 Tomcat 请求线程。若你用了 @Scheduled、CompletableFuture、自定义 ThreadPoolTaskExecutor,需显式包装执行逻辑。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
推荐做法:
- 对定时任务:用
Sentry.captureException()手动上报 - 对线程池:继承
ThreadPoolTaskExecutor,重写execute()和submit(),用try-catch包裹并上报 - 更简洁方式:使用 Sentry 提供的
SentryExecutorService包装器(v6.25+)
示例(包装 Scheduled 方法):
@Scheduled(fixedDelay = 60_000)
public void syncDataJob() {
try {
doSync();
} catch (Exception e) {
Sentry.captureException(e);
throw e; // 保持原有异常传播行为
}
}
Bugu 的接入要点(区别于 Sentry)
Bugu 是国内服务,接入更轻量,但默认不自动 hook JVM 异常。需手动注册全局处理器:
- 添加依赖:
com.bugu:bugu-java-sdk - 初始化时调用
BuguClient.init("your-app-key") - 主动注册异常处理器:
Thread.setDefaultUncaughtExceptionHandler(BuguClient::captureException) - Bugu 支持设置用户标识(如登录 ID)、自定义标签(如租户、模块名),建议在上报前填充
示例:
BuguClient.init("APP-KEY-XXX")
.setUserId("user123")
.addTag("module", "order-service");
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
BuguClient.captureException(e)
.setExtra("threadName", t.getName())
.send();
});
增强异常上下文,提升排查效率
光有堆栈不够。线上问题需要关联请求 ID、用户、环境、参数等。可在 Sentry/Bugu 上报前注入上下文:
- Sentry:用
Sentry.setExtra()、Sentry.setTag()、Sentry.setUser();配合 MDC(如 Logback 的%X{traceId})提取请求唯一标识 - Bugu:调用
.setExtra(key, value)或.addTag();建议在过滤器或拦截器中统一设置 traceId / userId - 避免敏感信息:不要传密码、token、银行卡号等,SDK 一般不自动过滤,需业务层清洗
小技巧:Sentry 支持 BeforeSendCallback 对事件做最后加工(比如过滤测试环境、脱敏字段)。

















