使用opentracing api(http://opentracing.io)跟踪检测

opentracing-instrumentation的Python项目详细描述


PyPI versionBuild StatusCoverage Status

opentracing python工具

用于启用跟踪的检测工具的集合 OpenTracing API

模块

确保运行的pipsetuptools版本足够新,例如,在安装项目需求之前,请执行以下操作:

pip install --upgrade "setuptools>=29" "pip>=9"

模块名是opentracing_instrumentation

里面是什么

支持的客户端框架

在本模块中检测以下库以进行跟踪:

  • boto3-aws python的sdk
  • Celery-分布式任务队列
  • urllib2
  • requests
  • SQLAlchemy
  • MySQLdb
  • psycopg2
  • Tornado HTTP客户端
  • redis

服务器检测

对于入站请求,提供了帮助函数before_request,用于为flask和uwsgi等框架创建中间件。

手动仪表

最后,为手动检测提供了一个@traced_function装饰器。

进程内上下文传播

作为opentracing 2.0api的一部分,进程内传播通过新定义的 ScopeManager 接口。然而,现有的功能一直保持以提供向后兼容性。 简化代码迁移:

span_in_context()使用当前的opentracing.tracer.scope_manager实现上下文传播, 应为基于线程本地的ScopeManager,例如opentracing.scope_managers.ThreadLocalScopeManager

span_in_stack_context()实现Tornado应用程序的上下文传播 也使用当前的opentracing.tracer.scope_manager,应该是 opentracing.scope_managers.tornado.TornadoScopeManager

get_current_span()返回当前活动的Span(如果有)。

直接访问request_context模块以及RequestContextRequestContextManager的用法 已经完全弃用,因为它们没有与新的opentracing 2.0api集成。 将它们与get_current_span()一起使用是有保证的,但是强烈建议 切换到前面提到的功能。

用法

此库提供两种类型的检测,显式检测 对于服务器终结点和客户端调用站点的隐式检测。

通过创建一个中间件类来检测服务器端点:

  1. 初始化特定的跟踪程序实现
  2. 将传入的请求处理程序包装到读取传入的 从请求跟踪信息并创建新的跟踪范围

通过执行一组 可用的client_hooks猴子在几个 公共库,如SQLAlchemyurllib2、tornado async http client。 这些钩子的初始化通常也是通过中间件完成的 类的__init__方法。

有一个客户端-服务器示例将此库与Flask工具一起使用 来自opentracing contrib:https://github.com/opentracing-contrib/python-flask/tree/master/example

下面是Clay framework

的中间件示例
fromopentracing_instrumentationimportspan_in_contextfromopentracing_instrumentation.http_serverimportbefore_requestfromopentracing_instrumentation.http_serverimportWSGIRequestWrapperfromopentracing_instrumentation.client_hooksimportinstall_all_patchesclassTracerMiddleware(object):def__init__(self,app,wsgi_app):self.wsgi_app=wsgi_appself.service_name=app.nameCONFIG.app_name=self.service_nameCONFIG.caller_name_headers.append('X-Uber-Source')CONFIG.callee_endpoint_headers.append('X-Uber-Endpoint')install_all_patches()self.wsgi_app=create_wsgi_middleware(wsgi_app)self.init_tracer()def__call__(self,environ,start_response):returnself.wsgi_app(environ,start_response)definit_tracer(self):# code specific to your tracer implementationpassdefcreate_wsgi_middleware(other_wsgi,tracer=None):"""    Create a wrapper middleware for another WSGI response handler.    If tracer is not passed in, 'opentracing.tracer' is used.    """defwsgi_tracing_middleware(environ,start_response):# TODO find out if the route can be retrieved from somewhererequest=WSGIRequestWrapper.from_wsgi_environ(environ)span=before_request(request=request,tracer=tracer)# Wrapper around the real start_response object to log# additional information to opentracing Spandefstart_response_wrapper(status,response_headers,exc_info=None):ifexc_infoisnotNone:span.set_tag('error',str(exc_info))span.finish()returnstart_response(status,response_headers)withspan_in_context(span):returnother_wsgi(environ,start_response_wrapper)returnwsgi_tracing_middleware

下面是Tornado应用程序中的中间件示例:

importopentracingfromopentracing.scope_managers.tornadoimportTornadoScopeManagerfromopentracing_instrumentationimportspan_in_stack_contextopentracing.tracer=MyOpenTracingTracer(scope_manager=TornadoScopeManager())classTracerMiddleware(object):def__init__(self):# perform initialization similar to above, including installing# the client_hooks@gen.coroutinedef__call__(self,request,handler,next_mw):request_wrapper=http_server.TornadoRequestWrapper(request=request)span=http_server.before_request(request=request_wrapper)@gen.coroutinedefnext_middleware_with_span():yieldnext_mw()yieldrun_coroutine_with_span(span=span,func=next_middleware_with_span)span.finish()defrun_coroutine_with_span(span,func,*args,**kwargs):"""Wrap the execution of a Tornado coroutine func in a tracing span.    This makes the span available through the get_current_span() function.    :param span: The tracing span to expose.    :param func: Co-routine to execute in the scope of tracing span.    :param args: Positional args to func, if any.    :param kwargs: Keyword args to func, if any.    """withspan_in_stack_context(span):returnfunc(*args,**kwargs)

定制

对于requests库,如果要设置自定义标记 要根据响应的内容或某些元数据进行跨越, 您可以设置response_handler_hook。 钩子必须是具有签名的方法(response, span), 其中responsespan是位置参数, 如果需要的话,你可以用不同的名字。

fromopentracing_instrumentation.client_hooks.requestsimportpatcherdefhook(response,span):ifnotresponse.ok:span.set_tag('error','true')patcher.set_response_handler_hook(hook)

如果获取父跨度有问题,可以重写 检索父跨距的默认函数。

fromopentracing_instrumentation.client_hooksimportinstall_all_patches,set_current_span_funcset_current_span_func(my_custom_extractor_func)install_all_patches()

开发

^某些测试需要{}、RabbitMQRedisDynamoDB

docker-compose up -d

要准备开发环境,请执行以下命令。

virtualenv env
source env/bin/activate
make bootstrap
make test

您也可以使用tox来运行测试。

tox

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
一组点之间的java快速插值   安卓 Java应用程序崩溃(NullPointerException)   java为什么我的回归不为冰雹工作?   java根据用户需要自动创建新变量   java UnsupportedClassVersionError在执行支持JDK8和JDK11的Jar文件时发生,这些文件是使用Maven的多版本Jar创建的   如何在Java中创建通用数组?   java io。grpc。StatusRuntimeException:未实现:未知服务manipula。核心2。果心原型。离心机   java有没有办法在安卓 studio中更新listView项目布局?   为什么@PostConstruct方法只能启动一个线程?   java Hibernate删除多对多惰性集合   如何从另一个Java类获取文本字段值   java从其他类访问数据   java正确持久化JSON对象   java Camel JMS SQS长轮询