使用Spring WebFlux时New Relic APM中缺失堆栈跟踪
你遇到的是New Relic Java Agent与Spring WebFlux(基于Reactor)的异常追踪兼容性问题,在老版本Agent中确实存在这类情况,更像是Agent的适配bug而非配置遗漏,下面分原因和解决方案详细说明:
问题根源
Spring WebFlux依赖Reactor框架处理异步请求,当异常发生时,Reactor会将原始异常包装在FluxOnAssembly$OnAssemblyException中,同时保留完整的调用堆栈。但你使用的New Relic Java Agent 5.9.0版本比较老旧(2020年发布),对Reactor的这种异常包装结构支持不足,无法正确解析并提取原始异常的完整信息,导致在Errors页面只显示通用的"Internal Server Error",而非实际的异常详情和堆栈。
解决方案
1. 优先升级New Relic Java Agent版本
这是最直接有效的解决办法。New Relic后续版本(比如6.x及以上)针对Spring WebFlux和Reactor的异常追踪做了大量适配优化,能够正确识别并解析Reactor包装的异常,完整上报堆栈信息。建议升级到最新稳定版,或者至少升级到6.0以上的版本。
2. 检查New Relic配置确保异常捕获正常
确认你的newrelic.yml配置文件中,错误收集相关配置正确:
error_collector: enabled: true capture_stack_traces: true ignore_errors: # 确保这里没有包含你的自定义异常com.example.SomeException - java.lang.IllegalStateException
3. 自定义异常上报(临时 workaround)
如果暂时无法升级Agent,可以在WebFlux的全局异常处理器中,手动调用New Relic的API上报原始异常:
import com.newrelic.api.agent.NewRelic; import reactor.core.publisher.FluxOnAssembly; import org.springframework.web.server.WebExceptionHandler; // 其他必要导入 @Component public class CustomWebExceptionHandler implements WebExceptionHandler { @Override public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) { // 提取被Reactor包装的原始异常 Throwable originalException = ex; if (ex instanceof FluxOnAssembly.FluxOnAssemblyException) { originalException = ((FluxOnAssembly.FluxOnAssemblyException) ex).getCause(); } // 手动上报给New Relic NewRelic.noticeError(originalException); // 保留原有异常响应处理逻辑 // ... } }
这样可以绕开Agent的自动捕获逻辑,直接将原始异常的完整堆栈上报到New Relic。
验证
完成升级或配置后,重新触发异常,查看New Relic APM的Events > Errors页面,应该能看到包含完整堆栈信息的异常详情了。
内容的提问来源于stack exchange,提问作者pixel

