Esempio n. 1
0
def traced_load_middleware(django, pin, func, instance, args, kwargs):
    """Patches django.core.handlers.base.BaseHandler.load_middleware to instrument all middlewares."""
    settings_middleware = []
    # Gather all the middleware
    if getattr(django.conf.settings, "MIDDLEWARE", None):
        settings_middleware += django.conf.settings.MIDDLEWARE
    if getattr(django.conf.settings, "MIDDLEWARE_CLASSES", None):
        settings_middleware += django.conf.settings.MIDDLEWARE_CLASSES

    # Iterate over each middleware provided in settings.py
    # Each middleware can either be a function or a class
    for mw_path in settings_middleware:
        mw = django.utils.module_loading.import_string(mw_path)

        # Instrument function-based middleware
        if isfunction(mw) and not iswrapped(mw):
            split = mw_path.split(".")
            if len(split) < 2:
                continue
            base = ".".join(split[:-1])
            attr = split[-1]

            # Function-based middleware is a factory which returns a handler function for requests.
            # So instead of tracing the factory, we want to trace its returned value.
            # We wrap the factory to return a traced version of the handler function.
            def wrapped_factory(func, instance, args, kwargs):
                # r is the middleware handler function returned from the factory
                r = func(*args, **kwargs)
                return wrapt.FunctionWrapper(
                    r,
                    traced_func(django, "django.middleware", resource=mw_path))

            wrap(base, attr, wrapped_factory)

        # Instrument class-based middleware
        elif isclass(mw):
            for hook in [
                    "process_request",
                    "process_response",
                    "process_view",
                    "process_template_response",
                    "__call__",
            ]:
                if hasattr(mw, hook) and not iswrapped(mw, hook):
                    wrap(
                        mw, hook,
                        traced_func(django,
                                    "django.middleware",
                                    resource=mw_path + ".{0}".format(hook)))
            # Do a little extra for `process_exception`
            if hasattr(mw, "process_exception") and not iswrapped(
                    mw, "process_exception"):
                res = mw_path + ".{0}".format("process_exception")
                wrap(
                    mw, "process_exception",
                    traced_process_exception(django,
                                             "django.middleware",
                                             resource=res))

    return func(*args, **kwargs)
Esempio n. 2
0
def instrument_caches(django):
    cache_backends = set([cache["BACKEND"] for cache in django.conf.settings.CACHES.values()])
    for cache_path in cache_backends:
        split = cache_path.split(".")
        cache_module = ".".join(split[:-1])
        cache_cls = split[-1]
        for method in ["get", "set", "add", "delete", "incr", "decr", "get_many", "set_many", "delete_many"]:
            try:
                cls = django.utils.module_loading.import_string(cache_path)
                # DEV: this can be removed when we add an idempotent `wrap`
                if not iswrapped(cls, method):
                    wrap(cache_module, "{0}.{1}".format(cache_cls, method), traced_cache(django))
            except Exception:
                log.debug("Error instrumenting cache %r", cache_path, exc_info=True)