We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Either opentracing SpanContextCorruptedException or no child spans
Using the ddtracer.opentracing exactly as in the example, just switching it out with the current Jaeger setup we're using, I get this exception on all requests:
```python
ERROR:root:tracer.extract() failed
 Traceback (most recent call last):
   File "/usr/local/lib/python3.6/site-packages/grpc_opentracing/_server.py", line 117, in _start_span
     opentracing.Format.HTTP_HEADERS, dict(metadata))
   File "/usr/local/lib/python3.6/site-packages/ddtrace/opentracer/tracer.py", line 291, in extract
     return propagator.extract(carrier)
   File "/usr/local/lib/python3.6/site-packages/ddtrace/opentracer/propagation/http.py", line 73, in extract
     raise SpanContextCorruptedException('failed to extract span context')
 opentracing.propagation.SpanContextCorruptedException: failed to extract span context
```
The spans do make it do datadog though, they're just errors of course:
![screenshot from 2018-09-16 01 48 50](https://user-images.githubusercontent.com/9902896/45591422-be8a6d80-b952-11e8-95f3-271fe5130fd8.png)

Using Python 3.6.6 with ddtrace[opentracing] and grpcio-opentracing 1.1.3, running the apps with `ddtrace-run`.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ddtrace/opentracer/tracer.py`
Content:
```
1 import logging
2 import opentracing
3 from opentracing import Format
4 from opentracing.scope_managers import ThreadLocalScopeManager
5 
6 import ddtrace
7 from ddtrace import Tracer as DatadogTracer
8 from ddtrace.constants import FILTERS_KEY
9 from ddtrace.settings import ConfigException
10 from ddtrace.utils import merge_dicts
11 from ddtrace.utils.config import get_application_name
12 
13 from .propagation import HTTPPropagator
14 from .span import Span
15 from .span_context import SpanContext
16 from .settings import ConfigKeys as keys, config_invalid_keys
17 from .utils import get_context_provider_for_scope_manager
18 
19 log = logging.getLogger(__name__)
20 
21 DEFAULT_CONFIG = {
22     keys.AGENT_HOSTNAME: 'localhost',
23     keys.AGENT_PORT: 8126,
24     keys.DEBUG: False,
25     keys.ENABLED: True,
26     keys.GLOBAL_TAGS: {},
27     keys.SAMPLER: None,
28     keys.PRIORITY_SAMPLING: None,
29     keys.SETTINGS: {
30         FILTERS_KEY: [],
31     },
32 }
33 
34 
35 class Tracer(opentracing.Tracer):
36     """A wrapper providing an OpenTracing API for the Datadog tracer."""
37 
38     def __init__(self, service_name=None, config=None, scope_manager=None, dd_tracer=None):
39         """Initialize a new Datadog opentracer.
40 
41         :param service_name: (optional) the name of the service that this
42             tracer will be used with. Note if not provided, a service name will
43             try to be determined based off of ``sys.argv``. If this fails a
44             :class:`ddtrace.settings.ConfigException` will be raised.
45         :param config: (optional) a configuration object to specify additional
46             options. See the documentation for further information.
47         :param scope_manager: (optional) the scope manager for this tracer to
48             use. The available managers are listed in the Python OpenTracing repo
49             here: https://github.com/opentracing/opentracing-python#scope-managers.
50             If ``None`` is provided, defaults to
51             :class:`opentracing.scope_managers.ThreadLocalScopeManager`.
52         :param dd_tracer: (optional) the Datadog tracer for this tracer to use. This
53             should only be passed if a custom Datadog tracer is being used. Defaults
54             to the global ``ddtrace.tracer`` tracer.
55         """
56         # Merge the given config with the default into a new dict
57         config = config or {}
58         self._config = merge_dicts(DEFAULT_CONFIG, config)
59 
60         # Pull out commonly used properties for performance
61         self._service_name = service_name or get_application_name()
62         self._enabled = self._config.get(keys.ENABLED)
63         self._debug = self._config.get(keys.DEBUG)
64 
65         if self._debug:
66             # Ensure there are no typos in any of the keys
67             invalid_keys = config_invalid_keys(self._config)
68             if invalid_keys:
69                 str_invalid_keys = ','.join(invalid_keys)
70                 raise ConfigException('invalid key(s) given (%s)'.format(str_invalid_keys))
71 
72         if not self._service_name:
73             raise ConfigException(""" Cannot detect the \'service_name\'.
74                                       Please set the \'service_name=\'
75                                       keyword argument.
76                                   """)
77 
78         self._scope_manager = scope_manager or ThreadLocalScopeManager()
79 
80         dd_context_provider = get_context_provider_for_scope_manager(self._scope_manager)
81 
82         self._dd_tracer = dd_tracer or ddtrace.tracer or DatadogTracer()
83         self._dd_tracer.configure(enabled=self._enabled,
84                                   hostname=self._config.get(keys.AGENT_HOSTNAME),
85                                   port=self._config.get(keys.AGENT_PORT),
86                                   sampler=self._config.get(keys.SAMPLER),
87                                   settings=self._config.get(keys.SETTINGS),
88                                   priority_sampling=self._config.get(keys.PRIORITY_SAMPLING),
89                                   context_provider=dd_context_provider,
90                                   )
91         self._propagators = {
92             Format.HTTP_HEADERS: HTTPPropagator(),
93             Format.TEXT_MAP: HTTPPropagator(),
94         }
95 
96     @property
97     def scope_manager(self):
98         """Returns the scope manager being used by this tracer."""
99         return self._scope_manager
100 
101     def start_active_span(self, operation_name, child_of=None, references=None,
102                           tags=None, start_time=None, ignore_active_span=False,
103                           finish_on_close=True):
104         """Returns a newly started and activated `Scope`.
105         The returned `Scope` supports with-statement contexts. For example::
106 
107             with tracer.start_active_span('...') as scope:
108                 scope.span.set_tag('http.method', 'GET')
109                 do_some_work()
110             # Span.finish() is called as part of Scope deactivation through
111             # the with statement.
112 
113         It's also possible to not finish the `Span` when the `Scope` context
114         expires::
115 
116             with tracer.start_active_span('...',
117                                           finish_on_close=False) as scope:
118                 scope.span.set_tag('http.method', 'GET')
119                 do_some_work()
120             # Span.finish() is not called as part of Scope deactivation as
121             # `finish_on_close` is `False`.
122 
123         :param operation_name: name of the operation represented by the new
124             span from the perspective of the current service.
125         :param child_of: (optional) a Span or SpanContext instance representing
126             the parent in a REFERENCE_CHILD_OF Reference. If specified, the
127             `references` parameter must be omitted.
128         :param references: (optional) a list of Reference objects that identify
129             one or more parent SpanContexts. (See the Reference documentation
130             for detail).
131         :param tags: an optional dictionary of Span Tags. The caller gives up
132             ownership of that dictionary, because the Tracer may use it as-is
133             to avoid extra data copying.
134         :param start_time: an explicit Span start time as a unix timestamp per
135             time.time().
136         :param ignore_active_span: (optional) an explicit flag that ignores
137             the current active `Scope` and creates a root `Span`.
138         :param finish_on_close: whether span should automatically be finished
139             when `Scope.close()` is called.
140         :return: a `Scope`, already registered via the `ScopeManager`.
141         """
142         otspan = self.start_span(
143             operation_name=operation_name,
144             child_of=child_of,
145             references=references,
146             tags=tags,
147             start_time=start_time,
148             ignore_active_span=ignore_active_span,
149         )
150 
151         # activate this new span
152         scope = self._scope_manager.activate(otspan, finish_on_close)
153 
154         return scope
155 
156     def start_span(self, operation_name=None, child_of=None, references=None,
157                    tags=None, start_time=None, ignore_active_span=False):
158         """Starts and returns a new Span representing a unit of work.
159 
160         Starting a root Span (a Span with no causal references)::
161 
162             tracer.start_span('...')
163 
164         Starting a child Span (see also start_child_span())::
165 
166             tracer.start_span(
167                 '...',
168                 child_of=parent_span)
169 
170         Starting a child Span in a more verbose way::
171 
172             tracer.start_span(
173                 '...',
174                 references=[opentracing.child_of(parent_span)])
175 
176         Note: the precedence when defining a relationship is the following:
177         (highest)
178             1. *child_of*
179             2. *references*
180             3. `scope_manager.active` (unless *ignore_active_span* is True)
181             4. None
182         (lowest)
183 
184         Currently Datadog only supports `child_of` references.
185 
186         :param operation_name: name of the operation represented by the new
187             span from the perspective of the current service.
188         :param child_of: (optional) a Span or SpanContext instance representing
189             the parent in a REFERENCE_CHILD_OF Reference. If specified, the
190             `references` parameter must be omitted.
191         :param references: (optional) a list of Reference objects that identify
192             one or more parent SpanContexts. (See the Reference documentation
193             for detail)
194         :param tags: an optional dictionary of Span Tags. The caller gives up
195             ownership of that dictionary, because the Tracer may use it as-is
196             to avoid extra data copying.
197         :param start_time: an explicit Span start time as a unix timestamp per
198             time.time()
199         :param ignore_active_span: an explicit flag that ignores the current
200             active `Scope` and creates a root `Span`.
201         :return: an already-started Span instance.
202         """
203         ot_parent = None          # 'ot_parent' is more readable than 'child_of'
204         ot_parent_context = None  # the parent span's context
205         dd_parent = None          # the child_of to pass to the ddtracer
206 
207         if child_of is not None:
208             ot_parent = child_of      # 'ot_parent' is more readable than 'child_of'
209         elif references and isinstance(references, list):
210             # we currently only support child_of relations to one span
211             ot_parent = references[0].referenced_context
212 
213         # - whenever child_of is not None ddspans with parent-child
214         #   relationships will share a ddcontext which maintains a hierarchy of
215         #   ddspans for the execution flow
216         # - when child_of is a ddspan then the ddtracer uses this ddspan to
217         #   create the child ddspan
218         # - when child_of is a ddcontext then the ddtracer uses the ddcontext to
219         #   get_current_span() for the parent
220         if ot_parent is None and not ignore_active_span:
221             # attempt to get the parent span from the scope manager
222             scope = self._scope_manager.active
223             parent_span = getattr(scope, 'span', None)
224             ot_parent_context = getattr(parent_span, 'context', None)
225             # we want the ddcontext of the active span in order to maintain the
226             # ddspan hierarchy
227             dd_parent = getattr(ot_parent_context, '_dd_context', None)
228 
229             # if we cannot get the context then try getting it from the DD tracer
230             # this emulates the behaviour of tracer.trace()
231             if dd_parent is None:
232                 dd_parent = self._dd_tracer.get_call_context()
233         elif ot_parent is not None and isinstance(ot_parent, Span):
234             # a span is given to use as a parent
235             ot_parent_context = ot_parent.context
236             dd_parent = ot_parent._dd_span
237         elif ot_parent is not None and isinstance(ot_parent, SpanContext):
238             # a span context is given to use to find the parent ddspan
239             dd_parent = ot_parent._dd_context
240         elif ot_parent is None:
241             # user wants to create a new parent span we don't have to do
242             # anything
243             pass
244         else:
245             raise TypeError('invalid span configuration given')
246 
247         # create a new otspan and ddspan using the ddtracer and associate it
248         # with the new otspan
249         ddspan = self._dd_tracer.start_span(
250             name=operation_name,
251             child_of=dd_parent,
252             service=self._service_name,
253         )
254 
255         # set the start time if one is specified
256         ddspan.start = start_time or ddspan.start
257         if tags is not None:
258             ddspan.set_tags(tags)
259 
260         otspan = Span(self, ot_parent_context, operation_name)
261         # sync up the OT span with the DD span
262         otspan._associate_dd_span(ddspan)
263 
264         return otspan
265 
266     def inject(self, span_context, format, carrier):
267         """Injects a span context into a carrier.
268 
269         :param span_context: span context to inject.
270         :param format: format to encode the span context with.
271         :param carrier: the carrier of the encoded span context.
272         """
273         propagator = self._propagators.get(format, None)
274 
275         if propagator is None:
276             raise opentracing.UnsupportedFormatException
277 
278         propagator.inject(span_context, carrier)
279 
280     def extract(self, format, carrier):
281         """Extracts a span context from a carrier.
282 
283         :param format: format that the carrier is encoded with.
284         :param carrier: the carrier to extract from.
285         """
286         propagator = self._propagators.get(format, None)
287 
288         if propagator is None:
289             raise opentracing.UnsupportedFormatException
290 
291         return propagator.extract(carrier)
292
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ddtrace/opentracer/tracer.py b/ddtrace/opentracer/tracer.py
--- a/ddtrace/opentracer/tracer.py
+++ b/ddtrace/opentracer/tracer.py
@@ -288,4 +288,9 @@
         if propagator is None:
             raise opentracing.UnsupportedFormatException
 
-        return propagator.extract(carrier)
+        # we have to manually activate the returned context from a distributed
+        # trace
+        ot_span_ctx = propagator.extract(carrier)
+        dd_span_ctx = ot_span_ctx._dd_context
+        self._dd_tracer.context_provider.activate(dd_span_ctx)
+        return ot_span_ctx

{"golden_diff": "diff --git a/ddtrace/opentracer/tracer.py b/ddtrace/opentracer/tracer.py\n--- a/ddtrace/opentracer/tracer.py\n+++ b/ddtrace/opentracer/tracer.py\n@@ -288,4 +288,9 @@\n         if propagator is None:\n             raise opentracing.UnsupportedFormatException\n \n-        return propagator.extract(carrier)\n+        # we have to manually activate the returned context from a distributed\n+        # trace\n+        ot_span_ctx = propagator.extract(carrier)\n+        dd_span_ctx = ot_span_ctx._dd_context\n+        self._dd_tracer.context_provider.activate(dd_span_ctx)\n+        return ot_span_ctx\n", "issue": "Either opentracing SpanContextCorruptedException or no child spans\nUsing the ddtracer.opentracing exactly as in the example, just switching it out with the current Jaeger setup we're using, I get this exception on all requests:\r\n```python\r\nERROR:root:tracer.extract() failed\r\n Traceback (most recent call last):\r\n   File \"/usr/local/lib/python3.6/site-packages/grpc_opentracing/_server.py\", line 117, in _start_span\r\n     opentracing.Format.HTTP_HEADERS, dict(metadata))\r\n   File \"/usr/local/lib/python3.6/site-packages/ddtrace/opentracer/tracer.py\", line 291, in extract\r\n     return propagator.extract(carrier)\r\n   File \"/usr/local/lib/python3.6/site-packages/ddtrace/opentracer/propagation/http.py\", line 73, in extract\r\n     raise SpanContextCorruptedException('failed to extract span context')\r\n opentracing.propagation.SpanContextCorruptedException: failed to extract span context\r\n```\r\nThe spans do make it do datadog though, they're just errors of course:\r\n![screenshot from 2018-09-16 01 48 50](https://user-images.githubusercontent.com/9902896/45591422-be8a6d80-b952-11e8-95f3-271fe5130fd8.png)\r\n\r\nUsing Python 3.6.6 with ddtrace[opentracing] and grpcio-opentracing 1.1.3, running the apps with `ddtrace-run`.\r\n\n", "before_files": [{"content": "import logging\nimport opentracing\nfrom opentracing import Format\nfrom opentracing.scope_managers import ThreadLocalScopeManager\n\nimport ddtrace\nfrom ddtrace import Tracer as DatadogTracer\nfrom ddtrace.constants import FILTERS_KEY\nfrom ddtrace.settings import ConfigException\nfrom ddtrace.utils import merge_dicts\nfrom ddtrace.utils.config import get_application_name\n\nfrom .propagation import HTTPPropagator\nfrom .span import Span\nfrom .span_context import SpanContext\nfrom .settings import ConfigKeys as keys, config_invalid_keys\nfrom .utils import get_context_provider_for_scope_manager\n\nlog = logging.getLogger(__name__)\n\nDEFAULT_CONFIG = {\n    keys.AGENT_HOSTNAME: 'localhost',\n    keys.AGENT_PORT: 8126,\n    keys.DEBUG: False,\n    keys.ENABLED: True,\n    keys.GLOBAL_TAGS: {},\n    keys.SAMPLER: None,\n    keys.PRIORITY_SAMPLING: None,\n    keys.SETTINGS: {\n        FILTERS_KEY: [],\n    },\n}\n\n\nclass Tracer(opentracing.Tracer):\n    \"\"\"A wrapper providing an OpenTracing API for the Datadog tracer.\"\"\"\n\n    def __init__(self, service_name=None, config=None, scope_manager=None, dd_tracer=None):\n        \"\"\"Initialize a new Datadog opentracer.\n\n        :param service_name: (optional) the name of the service that this\n            tracer will be used with. Note if not provided, a service name will\n            try to be determined based off of ``sys.argv``. If this fails a\n            :class:`ddtrace.settings.ConfigException` will be raised.\n        :param config: (optional) a configuration object to specify additional\n            options. See the documentation for further information.\n        :param scope_manager: (optional) the scope manager for this tracer to\n            use. The available managers are listed in the Python OpenTracing repo\n            here: https://github.com/opentracing/opentracing-python#scope-managers.\n            If ``None`` is provided, defaults to\n            :class:`opentracing.scope_managers.ThreadLocalScopeManager`.\n        :param dd_tracer: (optional) the Datadog tracer for this tracer to use. This\n            should only be passed if a custom Datadog tracer is being used. Defaults\n            to the global ``ddtrace.tracer`` tracer.\n        \"\"\"\n        # Merge the given config with the default into a new dict\n        config = config or {}\n        self._config = merge_dicts(DEFAULT_CONFIG, config)\n\n        # Pull out commonly used properties for performance\n        self._service_name = service_name or get_application_name()\n        self._enabled = self._config.get(keys.ENABLED)\n        self._debug = self._config.get(keys.DEBUG)\n\n        if self._debug:\n            # Ensure there are no typos in any of the keys\n            invalid_keys = config_invalid_keys(self._config)\n            if invalid_keys:\n                str_invalid_keys = ','.join(invalid_keys)\n                raise ConfigException('invalid key(s) given (%s)'.format(str_invalid_keys))\n\n        if not self._service_name:\n            raise ConfigException(\"\"\" Cannot detect the \\'service_name\\'.\n                                      Please set the \\'service_name=\\'\n                                      keyword argument.\n                                  \"\"\")\n\n        self._scope_manager = scope_manager or ThreadLocalScopeManager()\n\n        dd_context_provider = get_context_provider_for_scope_manager(self._scope_manager)\n\n        self._dd_tracer = dd_tracer or ddtrace.tracer or DatadogTracer()\n        self._dd_tracer.configure(enabled=self._enabled,\n                                  hostname=self._config.get(keys.AGENT_HOSTNAME),\n                                  port=self._config.get(keys.AGENT_PORT),\n                                  sampler=self._config.get(keys.SAMPLER),\n                                  settings=self._config.get(keys.SETTINGS),\n                                  priority_sampling=self._config.get(keys.PRIORITY_SAMPLING),\n                                  context_provider=dd_context_provider,\n                                  )\n        self._propagators = {\n            Format.HTTP_HEADERS: HTTPPropagator(),\n            Format.TEXT_MAP: HTTPPropagator(),\n        }\n\n    @property\n    def scope_manager(self):\n        \"\"\"Returns the scope manager being used by this tracer.\"\"\"\n        return self._scope_manager\n\n    def start_active_span(self, operation_name, child_of=None, references=None,\n                          tags=None, start_time=None, ignore_active_span=False,\n                          finish_on_close=True):\n        \"\"\"Returns a newly started and activated `Scope`.\n        The returned `Scope` supports with-statement contexts. For example::\n\n            with tracer.start_active_span('...') as scope:\n                scope.span.set_tag('http.method', 'GET')\n                do_some_work()\n            # Span.finish() is called as part of Scope deactivation through\n            # the with statement.\n\n        It's also possible to not finish the `Span` when the `Scope` context\n        expires::\n\n            with tracer.start_active_span('...',\n                                          finish_on_close=False) as scope:\n                scope.span.set_tag('http.method', 'GET')\n                do_some_work()\n            # Span.finish() is not called as part of Scope deactivation as\n            # `finish_on_close` is `False`.\n\n        :param operation_name: name of the operation represented by the new\n            span from the perspective of the current service.\n        :param child_of: (optional) a Span or SpanContext instance representing\n            the parent in a REFERENCE_CHILD_OF Reference. If specified, the\n            `references` parameter must be omitted.\n        :param references: (optional) a list of Reference objects that identify\n            one or more parent SpanContexts. (See the Reference documentation\n            for detail).\n        :param tags: an optional dictionary of Span Tags. The caller gives up\n            ownership of that dictionary, because the Tracer may use it as-is\n            to avoid extra data copying.\n        :param start_time: an explicit Span start time as a unix timestamp per\n            time.time().\n        :param ignore_active_span: (optional) an explicit flag that ignores\n            the current active `Scope` and creates a root `Span`.\n        :param finish_on_close: whether span should automatically be finished\n            when `Scope.close()` is called.\n        :return: a `Scope`, already registered via the `ScopeManager`.\n        \"\"\"\n        otspan = self.start_span(\n            operation_name=operation_name,\n            child_of=child_of,\n            references=references,\n            tags=tags,\n            start_time=start_time,\n            ignore_active_span=ignore_active_span,\n        )\n\n        # activate this new span\n        scope = self._scope_manager.activate(otspan, finish_on_close)\n\n        return scope\n\n    def start_span(self, operation_name=None, child_of=None, references=None,\n                   tags=None, start_time=None, ignore_active_span=False):\n        \"\"\"Starts and returns a new Span representing a unit of work.\n\n        Starting a root Span (a Span with no causal references)::\n\n            tracer.start_span('...')\n\n        Starting a child Span (see also start_child_span())::\n\n            tracer.start_span(\n                '...',\n                child_of=parent_span)\n\n        Starting a child Span in a more verbose way::\n\n            tracer.start_span(\n                '...',\n                references=[opentracing.child_of(parent_span)])\n\n        Note: the precedence when defining a relationship is the following:\n        (highest)\n            1. *child_of*\n            2. *references*\n            3. `scope_manager.active` (unless *ignore_active_span* is True)\n            4. None\n        (lowest)\n\n        Currently Datadog only supports `child_of` references.\n\n        :param operation_name: name of the operation represented by the new\n            span from the perspective of the current service.\n        :param child_of: (optional) a Span or SpanContext instance representing\n            the parent in a REFERENCE_CHILD_OF Reference. If specified, the\n            `references` parameter must be omitted.\n        :param references: (optional) a list of Reference objects that identify\n            one or more parent SpanContexts. (See the Reference documentation\n            for detail)\n        :param tags: an optional dictionary of Span Tags. The caller gives up\n            ownership of that dictionary, because the Tracer may use it as-is\n            to avoid extra data copying.\n        :param start_time: an explicit Span start time as a unix timestamp per\n            time.time()\n        :param ignore_active_span: an explicit flag that ignores the current\n            active `Scope` and creates a root `Span`.\n        :return: an already-started Span instance.\n        \"\"\"\n        ot_parent = None          # 'ot_parent' is more readable than 'child_of'\n        ot_parent_context = None  # the parent span's context\n        dd_parent = None          # the child_of to pass to the ddtracer\n\n        if child_of is not None:\n            ot_parent = child_of      # 'ot_parent' is more readable than 'child_of'\n        elif references and isinstance(references, list):\n            # we currently only support child_of relations to one span\n            ot_parent = references[0].referenced_context\n\n        # - whenever child_of is not None ddspans with parent-child\n        #   relationships will share a ddcontext which maintains a hierarchy of\n        #   ddspans for the execution flow\n        # - when child_of is a ddspan then the ddtracer uses this ddspan to\n        #   create the child ddspan\n        # - when child_of is a ddcontext then the ddtracer uses the ddcontext to\n        #   get_current_span() for the parent\n        if ot_parent is None and not ignore_active_span:\n            # attempt to get the parent span from the scope manager\n            scope = self._scope_manager.active\n            parent_span = getattr(scope, 'span', None)\n            ot_parent_context = getattr(parent_span, 'context', None)\n            # we want the ddcontext of the active span in order to maintain the\n            # ddspan hierarchy\n            dd_parent = getattr(ot_parent_context, '_dd_context', None)\n\n            # if we cannot get the context then try getting it from the DD tracer\n            # this emulates the behaviour of tracer.trace()\n            if dd_parent is None:\n                dd_parent = self._dd_tracer.get_call_context()\n        elif ot_parent is not None and isinstance(ot_parent, Span):\n            # a span is given to use as a parent\n            ot_parent_context = ot_parent.context\n            dd_parent = ot_parent._dd_span\n        elif ot_parent is not None and isinstance(ot_parent, SpanContext):\n            # a span context is given to use to find the parent ddspan\n            dd_parent = ot_parent._dd_context\n        elif ot_parent is None:\n            # user wants to create a new parent span we don't have to do\n            # anything\n            pass\n        else:\n            raise TypeError('invalid span configuration given')\n\n        # create a new otspan and ddspan using the ddtracer and associate it\n        # with the new otspan\n        ddspan = self._dd_tracer.start_span(\n            name=operation_name,\n            child_of=dd_parent,\n            service=self._service_name,\n        )\n\n        # set the start time if one is specified\n        ddspan.start = start_time or ddspan.start\n        if tags is not None:\n            ddspan.set_tags(tags)\n\n        otspan = Span(self, ot_parent_context, operation_name)\n        # sync up the OT span with the DD span\n        otspan._associate_dd_span(ddspan)\n\n        return otspan\n\n    def inject(self, span_context, format, carrier):\n        \"\"\"Injects a span context into a carrier.\n\n        :param span_context: span context to inject.\n        :param format: format to encode the span context with.\n        :param carrier: the carrier of the encoded span context.\n        \"\"\"\n        propagator = self._propagators.get(format, None)\n\n        if propagator is None:\n            raise opentracing.UnsupportedFormatException\n\n        propagator.inject(span_context, carrier)\n\n    def extract(self, format, carrier):\n        \"\"\"Extracts a span context from a carrier.\n\n        :param format: format that the carrier is encoded with.\n        :param carrier: the carrier to extract from.\n        \"\"\"\n        propagator = self._propagators.get(format, None)\n\n        if propagator is None:\n            raise opentracing.UnsupportedFormatException\n\n        return propagator.extract(carrier)\n", "path": "ddtrace/opentracer/tracer.py"}], "after_files": [{"content": "import logging\nimport opentracing\nfrom opentracing import Format\nfrom opentracing.scope_managers import ThreadLocalScopeManager\n\nimport ddtrace\nfrom ddtrace import Tracer as DatadogTracer\nfrom ddtrace.constants import FILTERS_KEY\nfrom ddtrace.settings import ConfigException\nfrom ddtrace.utils import merge_dicts\nfrom ddtrace.utils.config import get_application_name\n\nfrom .propagation import HTTPPropagator\nfrom .span import Span\nfrom .span_context import SpanContext\nfrom .settings import ConfigKeys as keys, config_invalid_keys\nfrom .utils import get_context_provider_for_scope_manager\n\nlog = logging.getLogger(__name__)\n\nDEFAULT_CONFIG = {\n    keys.AGENT_HOSTNAME: 'localhost',\n    keys.AGENT_PORT: 8126,\n    keys.DEBUG: False,\n    keys.ENABLED: True,\n    keys.GLOBAL_TAGS: {},\n    keys.SAMPLER: None,\n    keys.PRIORITY_SAMPLING: None,\n    keys.SETTINGS: {\n        FILTERS_KEY: [],\n    },\n}\n\n\nclass Tracer(opentracing.Tracer):\n    \"\"\"A wrapper providing an OpenTracing API for the Datadog tracer.\"\"\"\n\n    def __init__(self, service_name=None, config=None, scope_manager=None, dd_tracer=None):\n        \"\"\"Initialize a new Datadog opentracer.\n\n        :param service_name: (optional) the name of the service that this\n            tracer will be used with. Note if not provided, a service name will\n            try to be determined based off of ``sys.argv``. If this fails a\n            :class:`ddtrace.settings.ConfigException` will be raised.\n        :param config: (optional) a configuration object to specify additional\n            options. See the documentation for further information.\n        :param scope_manager: (optional) the scope manager for this tracer to\n            use. The available managers are listed in the Python OpenTracing repo\n            here: https://github.com/opentracing/opentracing-python#scope-managers.\n            If ``None`` is provided, defaults to\n            :class:`opentracing.scope_managers.ThreadLocalScopeManager`.\n        :param dd_tracer: (optional) the Datadog tracer for this tracer to use. This\n            should only be passed if a custom Datadog tracer is being used. Defaults\n            to the global ``ddtrace.tracer`` tracer.\n        \"\"\"\n        # Merge the given config with the default into a new dict\n        config = config or {}\n        self._config = merge_dicts(DEFAULT_CONFIG, config)\n\n        # Pull out commonly used properties for performance\n        self._service_name = service_name or get_application_name()\n        self._enabled = self._config.get(keys.ENABLED)\n        self._debug = self._config.get(keys.DEBUG)\n\n        if self._debug:\n            # Ensure there are no typos in any of the keys\n            invalid_keys = config_invalid_keys(self._config)\n            if invalid_keys:\n                str_invalid_keys = ','.join(invalid_keys)\n                raise ConfigException('invalid key(s) given (%s)'.format(str_invalid_keys))\n\n        if not self._service_name:\n            raise ConfigException(\"\"\" Cannot detect the \\'service_name\\'.\n                                      Please set the \\'service_name=\\'\n                                      keyword argument.\n                                  \"\"\")\n\n        self._scope_manager = scope_manager or ThreadLocalScopeManager()\n\n        dd_context_provider = get_context_provider_for_scope_manager(self._scope_manager)\n\n        self._dd_tracer = dd_tracer or ddtrace.tracer or DatadogTracer()\n        self._dd_tracer.configure(enabled=self._enabled,\n                                  hostname=self._config.get(keys.AGENT_HOSTNAME),\n                                  port=self._config.get(keys.AGENT_PORT),\n                                  sampler=self._config.get(keys.SAMPLER),\n                                  settings=self._config.get(keys.SETTINGS),\n                                  priority_sampling=self._config.get(keys.PRIORITY_SAMPLING),\n                                  context_provider=dd_context_provider,\n                                  )\n        self._propagators = {\n            Format.HTTP_HEADERS: HTTPPropagator(),\n            Format.TEXT_MAP: HTTPPropagator(),\n        }\n\n    @property\n    def scope_manager(self):\n        \"\"\"Returns the scope manager being used by this tracer.\"\"\"\n        return self._scope_manager\n\n    def start_active_span(self, operation_name, child_of=None, references=None,\n                          tags=None, start_time=None, ignore_active_span=False,\n                          finish_on_close=True):\n        \"\"\"Returns a newly started and activated `Scope`.\n        The returned `Scope` supports with-statement contexts. For example::\n\n            with tracer.start_active_span('...') as scope:\n                scope.span.set_tag('http.method', 'GET')\n                do_some_work()\n            # Span.finish() is called as part of Scope deactivation through\n            # the with statement.\n\n        It's also possible to not finish the `Span` when the `Scope` context\n        expires::\n\n            with tracer.start_active_span('...',\n                                          finish_on_close=False) as scope:\n                scope.span.set_tag('http.method', 'GET')\n                do_some_work()\n            # Span.finish() is not called as part of Scope deactivation as\n            # `finish_on_close` is `False`.\n\n        :param operation_name: name of the operation represented by the new\n            span from the perspective of the current service.\n        :param child_of: (optional) a Span or SpanContext instance representing\n            the parent in a REFERENCE_CHILD_OF Reference. If specified, the\n            `references` parameter must be omitted.\n        :param references: (optional) a list of Reference objects that identify\n            one or more parent SpanContexts. (See the Reference documentation\n            for detail).\n        :param tags: an optional dictionary of Span Tags. The caller gives up\n            ownership of that dictionary, because the Tracer may use it as-is\n            to avoid extra data copying.\n        :param start_time: an explicit Span start time as a unix timestamp per\n            time.time().\n        :param ignore_active_span: (optional) an explicit flag that ignores\n            the current active `Scope` and creates a root `Span`.\n        :param finish_on_close: whether span should automatically be finished\n            when `Scope.close()` is called.\n        :return: a `Scope`, already registered via the `ScopeManager`.\n        \"\"\"\n        otspan = self.start_span(\n            operation_name=operation_name,\n            child_of=child_of,\n            references=references,\n            tags=tags,\n            start_time=start_time,\n            ignore_active_span=ignore_active_span,\n        )\n\n        # activate this new span\n        scope = self._scope_manager.activate(otspan, finish_on_close)\n\n        return scope\n\n    def start_span(self, operation_name=None, child_of=None, references=None,\n                   tags=None, start_time=None, ignore_active_span=False):\n        \"\"\"Starts and returns a new Span representing a unit of work.\n\n        Starting a root Span (a Span with no causal references)::\n\n            tracer.start_span('...')\n\n        Starting a child Span (see also start_child_span())::\n\n            tracer.start_span(\n                '...',\n                child_of=parent_span)\n\n        Starting a child Span in a more verbose way::\n\n            tracer.start_span(\n                '...',\n                references=[opentracing.child_of(parent_span)])\n\n        Note: the precedence when defining a relationship is the following:\n        (highest)\n            1. *child_of*\n            2. *references*\n            3. `scope_manager.active` (unless *ignore_active_span* is True)\n            4. None\n        (lowest)\n\n        Currently Datadog only supports `child_of` references.\n\n        :param operation_name: name of the operation represented by the new\n            span from the perspective of the current service.\n        :param child_of: (optional) a Span or SpanContext instance representing\n            the parent in a REFERENCE_CHILD_OF Reference. If specified, the\n            `references` parameter must be omitted.\n        :param references: (optional) a list of Reference objects that identify\n            one or more parent SpanContexts. (See the Reference documentation\n            for detail)\n        :param tags: an optional dictionary of Span Tags. The caller gives up\n            ownership of that dictionary, because the Tracer may use it as-is\n            to avoid extra data copying.\n        :param start_time: an explicit Span start time as a unix timestamp per\n            time.time()\n        :param ignore_active_span: an explicit flag that ignores the current\n            active `Scope` and creates a root `Span`.\n        :return: an already-started Span instance.\n        \"\"\"\n        ot_parent = None          # 'ot_parent' is more readable than 'child_of'\n        ot_parent_context = None  # the parent span's context\n        dd_parent = None          # the child_of to pass to the ddtracer\n\n        if child_of is not None:\n            ot_parent = child_of      # 'ot_parent' is more readable than 'child_of'\n        elif references and isinstance(references, list):\n            # we currently only support child_of relations to one span\n            ot_parent = references[0].referenced_context\n\n        # - whenever child_of is not None ddspans with parent-child\n        #   relationships will share a ddcontext which maintains a hierarchy of\n        #   ddspans for the execution flow\n        # - when child_of is a ddspan then the ddtracer uses this ddspan to\n        #   create the child ddspan\n        # - when child_of is a ddcontext then the ddtracer uses the ddcontext to\n        #   get_current_span() for the parent\n        if ot_parent is None and not ignore_active_span:\n            # attempt to get the parent span from the scope manager\n            scope = self._scope_manager.active\n            parent_span = getattr(scope, 'span', None)\n            ot_parent_context = getattr(parent_span, 'context', None)\n            # we want the ddcontext of the active span in order to maintain the\n            # ddspan hierarchy\n            dd_parent = getattr(ot_parent_context, '_dd_context', None)\n\n            # if we cannot get the context then try getting it from the DD tracer\n            # this emulates the behaviour of tracer.trace()\n            if dd_parent is None:\n                dd_parent = self._dd_tracer.get_call_context()\n        elif ot_parent is not None and isinstance(ot_parent, Span):\n            # a span is given to use as a parent\n            ot_parent_context = ot_parent.context\n            dd_parent = ot_parent._dd_span\n        elif ot_parent is not None and isinstance(ot_parent, SpanContext):\n            # a span context is given to use to find the parent ddspan\n            dd_parent = ot_parent._dd_context\n        elif ot_parent is None:\n            # user wants to create a new parent span we don't have to do\n            # anything\n            pass\n        else:\n            raise TypeError('invalid span configuration given')\n\n        # create a new otspan and ddspan using the ddtracer and associate it\n        # with the new otspan\n        ddspan = self._dd_tracer.start_span(\n            name=operation_name,\n            child_of=dd_parent,\n            service=self._service_name,\n        )\n\n        # set the start time if one is specified\n        ddspan.start = start_time or ddspan.start\n        if tags is not None:\n            ddspan.set_tags(tags)\n\n        otspan = Span(self, ot_parent_context, operation_name)\n        # sync up the OT span with the DD span\n        otspan._associate_dd_span(ddspan)\n\n        return otspan\n\n    def inject(self, span_context, format, carrier):\n        \"\"\"Injects a span context into a carrier.\n\n        :param span_context: span context to inject.\n        :param format: format to encode the span context with.\n        :param carrier: the carrier of the encoded span context.\n        \"\"\"\n        propagator = self._propagators.get(format, None)\n\n        if propagator is None:\n            raise opentracing.UnsupportedFormatException\n\n        propagator.inject(span_context, carrier)\n\n    def extract(self, format, carrier):\n        \"\"\"Extracts a span context from a carrier.\n\n        :param format: format that the carrier is encoded with.\n        :param carrier: the carrier to extract from.\n        \"\"\"\n        propagator = self._propagators.get(format, None)\n\n        if propagator is None:\n            raise opentracing.UnsupportedFormatException\n\n        # we have to manually activate the returned context from a distributed\n        # trace\n        ot_span_ctx = propagator.extract(carrier)\n        dd_span_ctx = ot_span_ctx._dd_context\n        self._dd_tracer.context_provider.activate(dd_span_ctx)\n        return ot_span_ctx\n", "path": "ddtrace/opentracer/tracer.py"}]}