diff --git a/ddtrace/contrib/pyramid/patch.py b/ddtrace/contrib/pyramid/patch.py index d3b94283d5a..fd77a7f8eba 100644 --- a/ddtrace/contrib/pyramid/patch.py +++ b/ddtrace/contrib/pyramid/patch.py @@ -1,7 +1,8 @@ import os from .trace import trace_pyramid, DD_TWEEN_NAME -from .constants import SETTINGS_SERVICE +from .constants import SETTINGS_SERVICE, SETTINGS_DISTRIBUTED_TRACING +from ...util import asbool import pyramid.config from pyramid.path import caller_package @@ -24,8 +25,10 @@ def patch(): def traced_init(wrapped, instance, args, kwargs): settings = kwargs.pop('settings', {}) service = os.environ.get('DATADOG_SERVICE_NAME') or 'pyramid' + distributed_tracing = asbool(os.environ.get('DATADOG_PYRAMID_DISTRIBUTED_TRACING')) or False trace_settings = { - SETTINGS_SERVICE : service, + SETTINGS_SERVICE: service, + SETTINGS_DISTRIBUTED_TRACING: distributed_tracing, } settings.update(trace_settings) # If the tweens are explicitly set with 'pyramid.tweens', we need to diff --git a/ddtrace/util.py b/ddtrace/util.py index f3d9e766b51..a7ec8cda666 100644 --- a/ddtrace/util.py +++ b/ddtrace/util.py @@ -100,6 +100,18 @@ def _get_original_method(thing, key): setattr(patchable, key, dest.__get__(patchable, patchable.__class__)) +def asbool(value): + """Convert the given String to a boolean object. Accepted + values are `True` and `1`.""" + if value is None: + return False + + if isinstance(value, bool): + return value + + return value.lower() in ("true", "1") + + def unwrap(obj, attr): f = getattr(obj, attr, None) if f and isinstance(f, wrapt.ObjectProxy) and hasattr(f, '__wrapped__'): diff --git a/tests/contrib/pyramid/test_pyramid_autopatch.py b/tests/contrib/pyramid/test_pyramid_autopatch.py index 075a6bdc1c2..b0609350515 100644 --- a/tests/contrib/pyramid/test_pyramid_autopatch.py +++ b/tests/contrib/pyramid/test_pyramid_autopatch.py @@ -13,7 +13,7 @@ from ...test_tracer import get_dummy_tracer from ...util import override_global_tracer -from .test_pyramid import PyramidTestCase +from .test_pyramid import PyramidTestCase, PyramidBase class TestPyramidAutopatch(PyramidTestCase): @@ -29,6 +29,28 @@ def get_settings(self): } +class TestPyramidDistributedTracing(PyramidBase): + instrument = False + + def test_distributed_tracing(self): + # ensure the Context is properly created + # if distributed tracing is enabled + headers = { + 'x-datadog-trace-id': '100', + 'x-datadog-parent-id': '42', + 'x-datadog-sampling-priority': '2', + } + res = self.app.get('/', headers=headers, status=200) + writer = self.tracer.writer + spans = writer.pop() + eq_(len(spans), 1) + # check the propagated Context + span = spans[0] + eq_(span.trace_id, 100) + eq_(span.parent_id, 42) + eq_(span.get_metric('_sampling_priority_v1'), 2) + + def _include_me(config): pass diff --git a/tests/contrib/test_utils.py b/tests/contrib/test_utils.py index f7b72b1c3d9..91c6610d7c6 100644 --- a/tests/contrib/test_utils.py +++ b/tests/contrib/test_utils.py @@ -1,6 +1,7 @@ from nose.tools import eq_ from ddtrace.contrib.util import func_name +from ddtrace.util import asbool from functools import partial class SomethingCallable(object): diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 00000000000..c0a021bf5d9 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,19 @@ +import unittest + +from nose.tools import eq_ + +from ddtrace.util import asbool + + +class TestUtilities(unittest.TestCase): + def test_asbool(self): + # ensure the value is properly cast + eq_(asbool("True"), True) + eq_(asbool("true"), True) + eq_(asbool("1"), True) + eq_(asbool("False"), False) + eq_(asbool("false"), False) + eq_(asbool(None), False) + eq_(asbool(""), False) + eq_(asbool(True), True) + eq_(asbool(False), False) diff --git a/tox.ini b/tox.ini index 14c718a0b4d..492ca7f3dcd 100644 --- a/tox.ini +++ b/tox.ini @@ -322,6 +322,7 @@ setenv = [pyramid_autopatch] setenv = DATADOG_SERVICE_NAME = foobar + DATADOG_PYRAMID_DISTRIBUTED_TRACING = True [testenv:py27-pyramid-autopatch17-webtest] setenv =