OpenTracing Python:分布式追踪的标准 API
文章目录
- OpenTracing Python:分布式追踪的标准 API
OpenTracing Python:分布式追踪的标准 API
OpenTracing 的 Python 实现opentracing-python,目前收获了 750 Star:
这个项目是 OpenTracing 组织维护的 Python 平台 API,为分布式追踪提供了一套标准化的接口。当前版本主要提供 API 定义和一个基础的 no-op 实现,让各类 instrumentation 库能够基于统一的接口来收集和传播分布式追踪上下文,而不需要绑定到具体的追踪后端。
在微服务架构中,一个用户请求往往会流经多个服务。如果没有追踪机制,定位性能瓶颈或排查故障将变得极为困难。OpenTracing 正是为了解决这一问题而设计的开放标准,而opentracing-python则是该标准在 Python 生态中的具体落地。
项目的核心工作围绕三个环节展开:
- 接收请求时,通过 inject/extract API 延续已有的追踪链路,创建 Span 对象
- 处理请求时,将当前 Span 存入请求本地的存储中,供后续创建子 Span 时取用
- 发起请求时,从本地存储取出当前 Span,创建子 Span,并通过 inject/extract API 将其嵌入到出站请求中
入站请求处理
服务端收到请求时的典型处理逻辑:
defhandle_request(request):span=before_request(request,opentracing.global_tracer())withtracer.scope_manager.activate(span,True)asscope:handle_request_for_real(request)defbefore_request(request,tracer):span_context=tracer.extract(format=Format.HTTP_HEADERS,carrier=request.headers,)span=tracer.start_span(operation_name=request.operation,child_of=span_context)span.set_tag('http.url',request.full_url)remote_ip=request.remote_ipifremote_ip:span.set_tag(tags.PEER_HOST_IPV4,remote_ip)returnspan这里的关键是从请求头中提取 span_context。如果请求中已存在活跃追踪,则延续该追踪;否则启动新的根 Span。
出站请求处理
服务向其他服务发起调用时,需要创建子 Span 并将追踪上下文传递出去:
defbefore_http_request(request,current_span_extractor):parent_span=current_span_extractor()outbound_span=opentracing.global_tracer().start_span(operation_name=request.operation,child_of=parent_span)outbound_span.set_tag('http.url',request.full_url)http_header_carrier={}opentracing.global_tracer().inject(span_context=outbound_span.context,format=Format.HTTP_HEADERS,carrier=http_header_carrier)forkey,valueinhttp_header_carrier.iteritems():request.add_header(key,value)returnoutbound_spanScope 与进程内传播
OpenTracing 要求每个 Tracer 都包含一个 ScopeManager,用于管理当前活跃的 Span。Scope 可以通过上下文管理器自动注册和清理:
withtracer.start_active_span('someWork',finish_on_close=True)asscope:# 执行业务逻辑如果需要手动管理 Scope:
span=tracer.start_span(operation_name='someWork')scope=tracer.scope_manager.activate(span,True)try:# 执行业务逻辑exceptExceptionase:span.set_tag('error','...')finally:scope.close()多框架支持
项目内置了多种 ScopeManager 实现,覆盖不同的异步框架:
fromopentracing.scope_managersimportThreadLocalScopeManagerfromopentracing.scope_managers.geventimportGeventScopeManagerfromopentracing.scope_managers.tornadoimportTornadoScopeManagerfromopentracing.scope_managers.asyncioimportAsyncioScopeManagerfromopentracing.scope_managers.contextvarsimportContextVarsScopeManager对于 asyncio 应用,推荐使用ContextVarsScopeManager。相比AsyncioScopeManager,它能自动将父 Span 传播到子协程、任务或回调中。
测试支持
项目还提供了 MockTracer 用于单元测试,无需接入真实的追踪后端即可验证 instrumentation 逻辑:
fromopentracing.mocktracerimportMockTracer tracer=MockTracer()withtracer.start_span('someWork')asspan:passspans=tracer.finished_spans()opentracing-python作为 OpenTracing 规范在 Python 生态中的官方实现,为构建可观测的分布式系统提供了基础层接口。instrumentation 库可以基于此 API 开发,而应用开发者则可以自由选择后端追踪系统。
ntracing-python` 作为 OpenTracing 规范在 Python 生态中的官方实现,为构建可观测的分布式系统提供了基础层接口。instrumentation 库可以基于此 API 开发,而应用开发者则可以自由选择后端追踪系统。
