PKG-INFO 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. Metadata-Version: 2.1
  2. Name: opentracing
  3. Version: 2.2.0
  4. Summary: OpenTracing API for Python. See documentation at http://opentracing.io
  5. Home-page: https://github.com/opentracing/opentracing-python
  6. Author: The OpenTracing Authors
  7. Author-email: opentracing@googlegroups.com
  8. License: Apache License 2.0
  9. Description:
  10. OpenTracing API for Python
  11. ==========================
  12. |GitterChat| |BuildStatus| |PyPI| |ReadTheDocs|
  13. This library is a Python platform API for OpenTracing.
  14. Required Reading
  15. ----------------
  16. In order to understand the Python platform API, one must first be familiar with
  17. the `OpenTracing project <http://opentracing.io>`_ and
  18. `terminology <http://opentracing.io/documentation/pages/spec.html>`_ more
  19. specifically.
  20. Status
  21. ------
  22. In the current version, ``opentracing-python`` provides only the API and a
  23. basic no-op implementation that can be used by instrumentation libraries to
  24. collect and propagate distributed tracing context.
  25. Future versions will include a reference implementation utilizing an
  26. abstract Recorder interface, as well as a
  27. `Zipkin <http://openzipkin.github.io>`_-compatible Tracer.
  28. Usage
  29. -----
  30. The work of instrumentation libraries generally consists of three steps:
  31. 1. When a service receives a new request (over HTTP or some other protocol),
  32. it uses OpenTracing's inject/extract API to continue an active trace, creating a
  33. Span object in the process. If the request does not contain an active trace,
  34. the service starts a new trace and a new *root* Span.
  35. 2. The service needs to store the current Span in some request-local storage,
  36. (called ``Span`` *activation*) where it can be retrieved from when a child Span must
  37. be created, e.g. in case of the service making an RPC to another service.
  38. 3. When making outbound calls to another service, the current Span must be
  39. retrieved from request-local storage, a child span must be created (e.g., by
  40. using the ``start_child_span()`` helper), and that child span must be embedded
  41. into the outbound request (e.g., using HTTP headers) via OpenTracing's
  42. inject/extract API.
  43. Below are the code examples for the previously mentioned steps. Implementation
  44. of request-local storage needed for step 2 is specific to the service and/or frameworks /
  45. instrumentation libraries it is using, exposed as a ``ScopeManager`` child contained
  46. as ``Tracer.scope_manager``. See details below.
  47. Inbound request
  48. ^^^^^^^^^^^^^^^
  49. Somewhere in your server's request handler code:
  50. .. code-block:: python
  51. def handle_request(request):
  52. span = before_request(request, opentracing.global_tracer())
  53. # store span in some request-local storage using Tracer.scope_manager,
  54. # using the returned `Scope` as Context Manager to ensure
  55. # `Span` will be cleared and (in this case) `Span.finish()` be called.
  56. with tracer.scope_manager.activate(span, True) as scope:
  57. # actual business logic
  58. handle_request_for_real(request)
  59. def before_request(request, tracer):
  60. span_context = tracer.extract(
  61. format=Format.HTTP_HEADERS,
  62. carrier=request.headers,
  63. )
  64. span = tracer.start_span(
  65. operation_name=request.operation,
  66. child_of(span_context))
  67. span.set_tag('http.url', request.full_url)
  68. remote_ip = request.remote_ip
  69. if remote_ip:
  70. span.set_tag(tags.PEER_HOST_IPV4, remote_ip)
  71. caller_name = request.caller_name
  72. if caller_name:
  73. span.set_tag(tags.PEER_SERVICE, caller_name)
  74. remote_port = request.remote_port
  75. if remote_port:
  76. span.set_tag(tags.PEER_PORT, remote_port)
  77. return span
  78. Outbound request
  79. ----------------
  80. Somewhere in your service that's about to make an outgoing call:
  81. .. code-block:: python
  82. from opentracing import tags
  83. from opentracing.propagation import Format
  84. from opentracing_instrumentation import request_context
  85. # create and serialize a child span and use it as context manager
  86. with before_http_request(
  87. request=out_request,
  88. current_span_extractor=request_context.get_current_span):
  89. # actual call
  90. return urllib2.urlopen(request)
  91. def before_http_request(request, current_span_extractor):
  92. op = request.operation
  93. parent_span = current_span_extractor()
  94. outbound_span = opentracing.global_tracer().start_span(
  95. operation_name=op,
  96. child_of=parent_span
  97. )
  98. outbound_span.set_tag('http.url', request.full_url)
  99. service_name = request.service_name
  100. host, port = request.host_port
  101. if service_name:
  102. outbound_span.set_tag(tags.PEER_SERVICE, service_name)
  103. if host:
  104. outbound_span.set_tag(tags.PEER_HOST_IPV4, host)
  105. if port:
  106. outbound_span.set_tag(tags.PEER_PORT, port)
  107. http_header_carrier = {}
  108. opentracing.global_tracer().inject(
  109. span_context=outbound_span,
  110. format=Format.HTTP_HEADERS,
  111. carrier=http_header_carrier)
  112. for key, value in http_header_carrier.iteritems():
  113. request.add_header(key, value)
  114. return outbound_span
  115. Scope and within-process propagation
  116. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  117. For getting/setting the current active ``Span`` in the used request-local storage,
  118. OpenTracing requires that every ``Tracer`` contains a ``ScopeManager`` that grants
  119. access to the active ``Span`` through a ``Scope``. Any ``Span`` may be transferred to
  120. another task or thread, but not ``Scope``.
  121. .. code-block:: python
  122. # Access to the active span is straightforward.
  123. scope = tracer.scope_manager.active()
  124. if scope is not None:
  125. scope.span.set_tag('...', '...')
  126. The common case starts a ``Scope`` that's automatically registered for intra-process
  127. propagation via ``ScopeManager``.
  128. Note that ``start_active_span('...')`` automatically finishes the span on ``Scope.close()``
  129. (``start_active_span('...', finish_on_close=False)`` does not finish it, in contrast).
  130. .. code-block:: python
  131. # Manual activation of the Span.
  132. span = tracer.start_span(operation_name='someWork')
  133. with tracer.scope_manager.activate(span, True) as scope:
  134. # Do things.
  135. # Automatic activation of the Span.
  136. # finish_on_close is a required parameter.
  137. with tracer.start_active_span('someWork', finish_on_close=True) as scope:
  138. # Do things.
  139. # Handling done through a try construct:
  140. span = tracer.start_span(operation_name='someWork')
  141. scope = tracer.scope_manager.activate(span, True)
  142. try:
  143. # Do things.
  144. except Exception as e:
  145. scope.set_tag('error', '...')
  146. finally:
  147. scope.finish()
  148. **If there is a Scope, it will act as the parent to any newly started Span** unless
  149. the programmer passes ``ignore_active_span=True`` at ``start_span()``/``start_active_span()``
  150. time or specified parent context explicitly:
  151. .. code-block:: python
  152. scope = tracer.start_active_span('someWork', ignore_active_span=True)
  153. Each service/framework ought to provide a specific ``ScopeManager`` implementation
  154. that relies on their own request-local storage (thread-local storage, or coroutine-based storage
  155. for asynchronous frameworks, for example).
  156. Scope managers
  157. ^^^^^^^^^^^^^^
  158. This project includes a set of ``ScopeManager`` implementations under the ``opentracing.scope_managers`` submodule, which can be imported on demand:
  159. .. code-block:: python
  160. from opentracing.scope_managers import ThreadLocalScopeManager
  161. There exist implementations for ``thread-local`` (the default instance of the submodule ``opentracing.scope_managers``), ``gevent``, ``Tornado`` and ``asyncio``:
  162. .. code-block:: python
  163. from opentracing.scope_managers.gevent import GeventScopeManager # requires gevent
  164. from opentracing.scope_managers.tornado import TornadoScopeManager # requires tornado<6
  165. from opentracing.scope_managers.asyncio import AsyncioScopeManager # requires Python 3.4 or newer.
  166. Development
  167. -----------
  168. Tests
  169. ^^^^^
  170. .. code-block:: sh
  171. virtualenv env
  172. . ./env/bin/activate
  173. make bootstrap
  174. make test
  175. You can use `tox <https://tox.readthedocs.io>`_ to run tests as well.
  176. .. code-block:: sh
  177. tox
  178. Testbed suite
  179. ^^^^^^^^^^^^^
  180. A testbed suite designed to test API changes and experimental features is included under the *testbed* directory. For more information, see the `Testbed README <testbed/README.md>`_.
  181. Instrumentation Tests
  182. ---------------------
  183. This project has a working design of interfaces for the OpenTracing API. There is a MockTracer to
  184. facilitate unit-testing of OpenTracing Python instrumentation.
  185. .. code-block:: python
  186. from opentracing.mocktracer import MockTracer
  187. tracer = MockTracer()
  188. with tracer.start_span('someWork') as span:
  189. pass
  190. spans = tracer.finished_spans()
  191. someWorkSpan = spans[0]
  192. Documentation
  193. ^^^^^^^^^^^^^
  194. .. code-block:: sh
  195. virtualenv env
  196. . ./env/bin/activate
  197. make bootstrap
  198. make docs
  199. The documentation is written to *docs/_build/html*.
  200. LICENSE
  201. ^^^^^^^
  202. `Apache 2.0 License <./LICENSE>`__.
  203. Releases
  204. ^^^^^^^^
  205. Before new release, add a summary of changes since last version to CHANGELOG.rst
  206. .. code-block:: sh
  207. pip install zest.releaser[recommended]
  208. prerelease
  209. release
  210. git push origin master --follow-tags
  211. python setup.py sdist upload -r pypi upload_docs -r pypi
  212. postrelease
  213. git push
  214. .. |GitterChat| image:: http://img.shields.io/badge/gitter-join%20chat%20%E2%86%92-brightgreen.svg
  215. :target: https://gitter.im/opentracing/public
  216. .. |BuildStatus| image:: https://travis-ci.org/opentracing/opentracing-python.svg?branch-master
  217. :target: https://travis-ci.org/opentracing/opentracing-python
  218. .. |PyPI| image:: https://badge.fury.io/py/opentracing.svg
  219. :target: https://badge.fury.io/py/opentracing
  220. .. |ReadTheDocs| image:: http://readthedocs.org/projects/opentracing-python/badge/?version=latest
  221. :target: https://opentracing-python.readthedocs.io/en/latest/?badge=latest
  222. :alt: Documentation Status
  223. Keywords: opentracing
  224. Platform: any
  225. Classifier: Development Status :: 5 - Production/Stable
  226. Classifier: Intended Audience :: Developers
  227. Classifier: License :: OSI Approved :: Apache Software License
  228. Classifier: Programming Language :: Python :: 2.7
  229. Classifier: Programming Language :: Python :: 3.5
  230. Classifier: Programming Language :: Python :: 3.6
  231. Classifier: Programming Language :: Python :: 3.7
  232. Classifier: Programming Language :: Python :: Implementation :: PyPy
  233. Classifier: Topic :: Software Development :: Libraries :: Python Modules
  234. Provides-Extra: tests