From bea9d9d49f0494ab469709780fc4aa4db898c5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torstein=20A=2E=20B=C3=B8?= Date: Tue, 18 May 2021 13:01:44 +0200 Subject: [PATCH 1/3] Django user data is set to be optional --- .../opencensus/ext/django/middleware.py | 6 ++- .../tests/test_django_middleware.py | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py b/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py index a8f12fdb0..032c21397 100644 --- a/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py +++ b/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py @@ -53,6 +53,7 @@ EXCLUDELIST_PATHS = 'EXCLUDELIST_PATHS' EXCLUDELIST_HOSTNAMES = 'EXCLUDELIST_HOSTNAMES' +INCLUDE_USER_DATA = 'INCLUDE_USER_DATA' log = logging.getLogger(__name__) @@ -169,6 +170,8 @@ def __init__(self, get_response=None): self.excludelist_hostnames = settings.get(EXCLUDELIST_HOSTNAMES, None) + self.include_user_data = settings.get(INCLUDE_USER_DATA, True) + if django.VERSION >= (2,): # pragma: NO COVER connection.execute_wrappers.append(_trace_db_call) @@ -263,7 +266,8 @@ def process_response(self, request, response): attribute_key=HTTP_STATUS_CODE, attribute_value=response.status_code) - _set_django_attributes(span, request) + if self.include_user_data: + _set_django_attributes(span, request) tracer = _get_current_tracer() tracer.end_span() diff --git a/contrib/opencensus-ext-django/tests/test_django_middleware.py b/contrib/opencensus-ext-django/tests/test_django_middleware.py index 522ea458c..0b806dc1a 100644 --- a/contrib/opencensus-ext-django/tests/test_django_middleware.py +++ b/contrib/opencensus-ext-django/tests/test_django_middleware.py @@ -236,6 +236,52 @@ def test_process_response(self): self.assertEqual(span.attributes, expected_attributes) + def test_no_user_data(self): + from opencensus.ext.django import middleware + + trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' + span_id = '6e0c63257de34c92' + django_trace_id = '00-{}-{}-00'.format(trace_id, span_id) + + django_request = RequestFactory().get('/wiki/Rabbit', **{ + 'traceparent': django_trace_id, + }) + + # Force the test request to be sampled + settings = type('Test', (object,), {}) + settings.OPENCENSUS = { + 'TRACE': { + 'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa + 'INCLUDE_USER_DATA': False + }, + } + patch_settings = mock.patch( + 'django.conf.settings', + settings) + + with patch_settings: + middleware_obj = middleware.OpencensusMiddleware() + + middleware_obj.process_request(django_request) + tracer = middleware._get_current_tracer() + span = tracer.current_span() + + exporter_mock = mock.Mock() + tracer.exporter = exporter_mock + + django_response = mock.Mock() + django_response.status_code = 200 + + mock_user = mock.Mock() + mock_user.pk = 123 + mock_user.get_username.return_value = 'test_name' + django_request.user = mock_user + + middleware_obj.process_response(django_request, django_response) + actual_attributes = span.attributes + self.assertNotIn('django.user.id', actual_attributes) + self.assertNotIn('django.user.name', actual_attributes) + def test_process_response_unfinished_child_span(self): from opencensus.ext.django import middleware From 25f5a360bde4ae8752e39350b763b46bb92ea7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torstein=20A=2E=20B=C3=B8?= Date: Tue, 18 May 2021 14:02:14 +0200 Subject: [PATCH 2/3] Django user data is set to be optional in exception handling --- .../opencensus/ext/django/middleware.py | 3 +- .../tests/test_django_middleware.py | 56 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py b/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py index 032c21397..22f05d7b1 100644 --- a/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py +++ b/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py @@ -299,6 +299,7 @@ def process_exception(self, request, exception): attribute_key=STACKTRACE, attribute_value='\n'.join(traceback.format_tb(tb))) - _set_django_attributes(span, request) + if self.include_user_data: + _set_django_attributes(span, 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 0b806dc1a..b5127079a 100644 --- a/contrib/opencensus-ext-django/tests/test_django_middleware.py +++ b/contrib/opencensus-ext-django/tests/test_django_middleware.py @@ -406,6 +406,62 @@ def test_process_exception(self): self.assertEqual(span.attributes, expected_attributes) + def test_process_exception_without_user_data(self): + from opencensus.ext.django import middleware + + trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' + span_id = '6e0c63257de34c92' + django_trace_id = '00-{}-{}-00'.format(trace_id, span_id) + + django_request = RequestFactory().get('/wiki/Rabbit', **{ + 'traceparent': django_trace_id, + }) + + # Force the test request to be sampled + settings = type('Test', (object,), {}) + settings.OPENCENSUS = { + 'TRACE': { + 'SAMPLER': 'opencensus.trace.samplers.AlwaysOnSampler()', # noqa + 'INCLUDE_USER_DATA': False + } + } + patch_settings = mock.patch( + 'django.conf.settings', + settings) + + with patch_settings: + middleware_obj = middleware.OpencensusMiddleware() + + tb = None + try: + raise RuntimeError("bork bork bork") + except Exception as exc: + test_exception = exc + if hasattr(exc, "__traceback__"): + tb = exc.__traceback__ + else: + _, _, tb = sys.exc_info() + + middleware_obj.process_request(django_request) + tracer = middleware._get_current_tracer() + span = tracer.current_span() + + exporter_mock = mock.Mock() + tracer.exporter = exporter_mock + + django_response = mock.Mock() + django_response.status_code = 200 + + mock_user = mock.Mock() + mock_user.pk = 123 + mock_user.get_username.return_value = 'test_name' + django_request.user = mock_user + + middleware_obj.process_exception(django_request, test_exception) + + self.assertNotIn('django.user.id', span.attributes) + self.assertNotIn('django.user.name', span.attributes) + class Test__set_django_attributes(unittest.TestCase): class Span(object): From 2f0a8cb9b8ed28970e1545d80b588f45e4366780 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torstein=20I=2E=20B=C3=B8?= Date: Wed, 17 Aug 2022 21:45:31 +0200 Subject: [PATCH 3/3] Fix django 4.1 issue --- .../opencensus-ext-django/opencensus/ext/django/middleware.py | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py b/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py index 77e499f3f..03ea9f096 100644 --- a/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py +++ b/contrib/opencensus-ext-django/opencensus/ext/django/middleware.py @@ -146,6 +146,7 @@ def _trace_db_call(execute, sql, params, many, context): class OpencensusMiddleware(MiddlewareMixin): """Saves the request in thread local""" + _is_coroutine=False def __init__(self, get_response=None): self.get_response = get_response