diff --git a/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py b/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py index d1da88ca5..02683d51e 100644 --- a/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py +++ b/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py @@ -188,7 +188,10 @@ def process_request(self, request): except Exception: # pragma: NO COVER log.error('Failed to trace request', exc_info=True) - def process_view(self, request, view_func, *args, **kwargs): + def get_span_name(self, request): + return utils.get_func_name(request.resolver_match.func) + + def process_view(self, request, *args, **kwargs): """Process view is executed before the view function, here we get the function name add set it as the span name. """ @@ -202,7 +205,7 @@ def process_view(self, request, view_func, *args, **kwargs): # function name of the request. tracer = _get_current_tracer() span = tracer.current_span() - span.name = utils.get_func_name(view_func) + span.name = self.get_span_name(request) except Exception: # pragma: NO COVER log.error('Failed to trace request', exc_info=True) diff --git a/contrib/opencensus-ext-django/tests/test_django_middleware.py b/contrib/opencensus-ext-django/tests/test_django_middleware.py index 15998e88c..cc5d09c79 100644 --- a/contrib/opencensus-ext-django/tests/test_django_middleware.py +++ b/contrib/opencensus-ext-django/tests/test_django_middleware.py @@ -32,6 +32,17 @@ class TestOpencensusMiddleware(unittest.TestCase): def setUp(self): from django.conf import settings as django_settings from django.test.utils import setup_test_environment + from opencensus.ext.django import middleware + from django.http import HttpResponse + from django.views import View + + self.middleware_kls = middleware.OpencensusMiddleware + + class MockViewOk(View): + def get(self, *args, **kwargs): + return HttpResponse(status=200) + + self.view_func_ok = MockViewOk.as_view() if not django_settings.configured: django_settings.configure() @@ -42,20 +53,19 @@ def tearDown(self): teardown_test_environment() def test_constructor_default(self): - from opencensus.ext.django import middleware - - middleware = middleware.OpencensusMiddleware() + middleware_obj = self.middleware_kls() - assert isinstance(middleware.sampler, samplers.ProbabilitySampler) - assert isinstance(middleware.exporter, print_exporter.PrintExporter) + assert isinstance(middleware_obj.sampler, samplers.ProbabilitySampler) assert isinstance( - middleware.propagator, + middleware_obj.exporter, + print_exporter.PrintExporter, + ) + assert isinstance( + middleware_obj.propagator, trace_context_http_header_format.TraceContextPropagator, ) def test_configuration(self): - from opencensus.ext.django import middleware - settings = type('Test', (object,), {}) settings.OPENCENSUS = { 'TRACE': { @@ -69,17 +79,21 @@ def test_configuration(self): settings) with patch_settings: - middleware = middleware.OpencensusMiddleware() + middleware_obj = self.middleware_kls() - assert isinstance(middleware.sampler, samplers.AlwaysOnSampler) - assert isinstance(middleware.exporter, print_exporter.PrintExporter) + assert isinstance(middleware_obj.sampler, samplers.AlwaysOnSampler) assert isinstance( - middleware.propagator, + middleware_obj.exporter, + print_exporter.PrintExporter, + ) + assert isinstance( + middleware_obj.propagator, trace_context_http_header_format.TraceContextPropagator, ) def test_process_request(self): from opencensus.ext.django import middleware + from django.urls.resolvers import ResolverMatch trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_id = '6e0c63257de34c92' @@ -87,6 +101,8 @@ def test_process_request(self): django_request = RequestFactory().get('/wiki/Rabbit', **{ 'HTTP_TRACEPARENT': django_trace_id}) + django_request.resolver_match = ResolverMatch( + self.view_func_ok, None, None) # Force the test request to be sampled settings = type('Test', (object,), {}) @@ -100,7 +116,7 @@ def test_process_request(self): settings) with patch_settings: - middleware_obj = middleware.OpencensusMiddleware() + middleware_obj = self.middleware_kls() # test process_request middleware_obj.process_request(django_request) @@ -123,11 +139,44 @@ def test_process_request(self): span_context = tracer.span_context self.assertEqual(span_context.trace_id, trace_id) + def test_process_view(self): + from opencensus.ext.django import middleware + from django.urls.resolvers import ResolverMatch + + trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' + span_id = '6e0c63257de34c92' + django_trace_id = '00-{}-{}-00'.format(trace_id, span_id) + + django_request = RequestFactory().get('/wiki/Rabbit', **{ + 'HTTP_TRACEPARENT': django_trace_id}) + django_request.resolver_match = ResolverMatch( + self.view_func_ok, None, None) + + # Force the test request to be sampled + settings = type('Test', (object,), {}) + settings.OPENCENSUS = { + 'TRACE': { + 'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa + } + } + patch_settings = mock.patch( + 'django.conf.settings', + settings) + + with patch_settings: + middleware_obj = self.middleware_kls() + + # test process_request + middleware_obj.process_request(django_request) + + tracer = middleware._get_current_tracer() + + span = tracer.current_span() + # test process_view - view_func = mock.Mock() - middleware_obj.process_view(django_request, view_func) + middleware_obj.process_view(django_request) - self.assertEqual(span.name, 'mock.mock.Mock') + self.assertEqual(span.name, 'test_django_middleware.MockViewOk') def test_blacklist_path(self): from opencensus.ext.django import middleware @@ -148,7 +197,7 @@ def test_blacklist_path(self): settings) with patch_settings: - middleware_obj = middleware.OpencensusMiddleware() + middleware_obj = self.middleware_kls() django_request = RequestFactory().get('/test_blacklist_path') disabled = utils.disable_tracing_url(django_request.path, @@ -163,8 +212,7 @@ def test_blacklist_path(self): span = tracer.current_span() # process view - view_func = mock.Mock() - middleware_obj.process_view(django_request, view_func) + middleware_obj.process_view(django_request) tracer = middleware._get_current_tracer() span = tracer.current_span() @@ -204,7 +252,7 @@ def test_process_response(self): settings) with patch_settings: - middleware_obj = middleware.OpencensusMiddleware() + middleware_obj = self.middleware_kls() middleware_obj.process_request(django_request) tracer = middleware._get_current_tracer() @@ -259,7 +307,7 @@ def test_process_response_unfinished_child_span(self): settings) with patch_settings: - middleware_obj = middleware.OpencensusMiddleware() + middleware_obj = self.middleware_kls() middleware_obj.process_request(django_request) tracer = middleware._get_current_tracer() @@ -294,6 +342,61 @@ def test_process_response_unfinished_child_span(self): self.assertEqual(span.attributes, expected_attributes) +class TestCustomisedOpencensusMiddleware(TestOpencensusMiddleware): + + def setUp(self): + super(TestCustomisedOpencensusMiddleware, self).setUp() + + from opencensus.ext.django import middleware + + class CustomisedOpencensusMiddleware(middleware.OpencensusMiddleware): + ''' Customize the span naming convention; prefix it with the service name. ''' # noqa + def get_span_name(self, request): + return "MyService." + super(CustomisedOpencensusMiddleware, self).get_span_name(request) # noqa + + self.middleware_kls = CustomisedOpencensusMiddleware + + def test_process_view(self): + from opencensus.ext.django import middleware + from django.urls.resolvers import ResolverMatch + + trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' + span_id = '6e0c63257de34c92' + django_trace_id = '00-{}-{}-00'.format(trace_id, span_id) + + django_request = RequestFactory().get('/wiki/Rabbit', **{ + 'HTTP_TRACEPARENT': django_trace_id}) + django_request.resolver_match = ResolverMatch( + self.view_func_ok, None, None) + + # Force the test request to be sampled + settings = type('Test', (object,), {}) + settings.OPENCENSUS = { + 'TRACE': { + 'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa + } + } + patch_settings = mock.patch( + 'django.conf.settings', + settings) + + with patch_settings: + middleware_obj = self.middleware_kls() + + # test process_request + middleware_obj.process_request(django_request) + + tracer = middleware._get_current_tracer() + + span = tracer.current_span() + + # test process_view + middleware_obj.process_view(django_request) + + self.assertEqual( + span.name, 'MyService.test_django_middleware.MockViewOk') + + class Test__set_django_attributes(unittest.TestCase): class Span(object): def __init__(self):