census-instrumentation / opencensus-python

A stats collection and distributed tracing framework
Apache License 2.0
669 stars 250 forks source link

Fixed support for Django 4.1 #1159

Closed JeremyVriens closed 2 years ago

JeremyVriens commented 2 years ago

This PR fixes the support for Django 4.1 according to this bug report: https://github.com/census-instrumentation/opencensus-python/issues/1154

The issue was a missing call to init of the super class, which worked fine before, but broke as of this change in Django: https://github.com/django/django/pull/15216

lzchen commented 2 years ago

@JeremyVriens Is this a breaking change for users who used MiddleWareMixin previously and didn't supply a get_response in the constructor?

JeremyVriens commented 2 years ago

When used correctly as described in the README, it should not be as Django passes the request through all the registered middlewares (see also their documentation: https://docs.djangoproject.com/en/4.1/topics/http/middleware/). The default value of None for the get_response argument was in that sense never correct.

ghost commented 2 years ago

When a release will be available for this fix?

oscarhermoso commented 2 years ago

If anyone is still waiting for this fix to be released, here is a snippet you can use to patch the middleware for now:

# myapp/settings.py

MIDDLEWARE = [
    # 'opencensus.ext.django.middleware.OpencensusMiddleware',
    'myapp.middleware.PatchedOpencensusMiddleware',
]
# myapp/middleware.py

import django
from opencensus.ext.django.middleware import (
    OpencensusMiddleware,
    EXCLUDELIST_PATHS,
    EXCLUDELIST_HOSTNAMES,
    _trace_db_call
)
import six
from django.db import connection
from opencensus.common import configuration
from opencensus.trace import (
    integrations,
    print_exporter,
    samplers,
)
from opencensus.trace.propagation import trace_context_http_header_format

class PatchedOpencensusMiddleware(OpencensusMiddleware):
    def __init__(self, get_response=None):
        super(OpencensusMiddleware, self).__init__(get_response)
        settings = getattr(django.conf.settings, 'OPENCENSUS', {})
        settings = settings.get('TRACE', {})

        self.sampler = (settings.get('SAMPLER', None)
                        or samplers.ProbabilitySampler())
        if isinstance(self.sampler, six.string_types):
            self.sampler = configuration.load(self.sampler)

        self.exporter = settings.get('EXPORTER', None) or \
            print_exporter.PrintExporter()
        if isinstance(self.exporter, six.string_types):
            self.exporter = configuration.load(self.exporter)

        self.propagator = settings.get('PROPAGATOR', None) or \
            trace_context_http_header_format.TraceContextPropagator()
        if isinstance(self.propagator, six.string_types):
            self.propagator = configuration.load(self.propagator)

        self.excludelist_paths = settings.get(EXCLUDELIST_PATHS, None)

        self.excludelist_hostnames = settings.get(EXCLUDELIST_HOSTNAMES, None)

        if django.VERSION >= (2,):  # pragma: NO COVER
            connection.execute_wrappers.append(_trace_db_call)

        # pylint: disable=protected-access
        integrations.add_integration(integrations._Integrations.DJANGO)
lzchen commented 2 years ago

https://github.com/census-instrumentation/opencensus-python/releases/tag/opencensus-ext-django%400.8.0 released.

oscarhermoso commented 2 years ago

Thanks @lzchen, not the first time you've helped me out. Super appreciated