如何让Python堆栈跟踪在Google Cloud Trace中正确显示?
GKE上FastAPI OTel链路追踪异常问题排查方案
1. 异常附加到所有跨度的原因与修复
这大概率是OTel Python SDK的异常传播逻辑配置问题。默认情况下,若没正确设置异常捕获边界,FastAPI、ASGI等多层instrumentation会重复捕获异常并附加到各自跨度上。
解决方法:
- 初始化FastAPI instrumentation时关闭子跨度的异常捕获,只让根跨度(如uvicorn入口跨度)处理异常:
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor FastAPIInstrumentor.instrument_app( app, capture_exception=False # 禁止FastAPI子跨度捕获异常 )
2. 堆栈跟踪截断、错误的问题修复
可能诱因
- OTel SDK默认未配置完整堆栈捕获,过滤了业务代码/uvicorn的栈帧;
- 旧版本Cloud Trace Exporter存在堆栈序列化截断bug;
- 自定义错误处理逻辑未获取原始完整堆栈。
修复步骤
强制开启完整堆栈捕获
初始化TracerProvider时,确保SpanProcessor保留完整堆栈信息,不要做额外过滤:from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor tracer_provider = TracerProvider() tracer_provider.add_span_processor(BatchSpanProcessor(cloud_trace_exporter))手动捕获原始异常堆栈
若自动捕获失效,在FastAPI全局异常处理器中手动把完整堆栈附加到根跨度:import traceback from fastapi import Request from opentelemetry.trace import get_current_span from fastapi.responses import JSONResponse @app.exception_handler(Exception) async def global_exception_handler(request: Request, exc: Exception): current_span = get_current_span() if current_span.is_recording(): # 获取完整堆栈信息 full_stack = traceback.format_exc() current_span.record_exception( exc, stack_trace=full_stack ) return JSONResponse( status_code=500, content={"detail": str(exc)} )升级OTel依赖版本
旧版本依赖可能存在序列化bug,执行升级命令:pip install --upgrade opentelemetry-sdk opentelemetry-instrumentation-fastapi opentelemetry-exporter-google-cloud-trace
3. 在Cloud Console查看真实堆栈的正确方式
- 打开Cloud Trace的Trace Details页面,定位到根跨度(通常命名为
uvicorn.request或对应接口的请求方法+路径); - 切换到Logs & Events标签,展开
exception字段查看stacktrace,配置正确后会显示包含uvicorn入口和业务代码的完整堆栈; - 若仍有问题,直接查看关联的Cloud Logs条目,日志中会保留完整的原始堆栈。
内容的提问来源于stack exchange,提问作者Bartek Banachewicz
相关产品推荐
相关产品推荐

