From Django’s context:

Middleware is a framework of hooks into Django’s request/response processing.
It’s a light, low-level “plugin” system for globally altering Django’s input or output.

Middleware is like a layer which processes every request and response. Instead of logging requests and responses in resp. views, its better to do at middleware layer which will log every incoming request. Why better?

  • it will log unhandled requests/views
  • one time job, no need to configure for every request/view

Here, we are using Django’s middleware semantics to construct a middleware which will log all requests and corresponding responses.

  • Create a middleware file

    We will create a RequestLogMiddleware class in /middleware/ in your <application> folder, like:

    Middleware to log `*/api/*` requests and responses.
    import socket
    import time
    import json
    import logging
    request_logger = logging.getLogger(__name__)
    class RequestLogMiddleware:
        """Request Logging Middleware."""
        def __init__(self, get_response):
            self.get_response = get_response
        def __call__(self, request):
            start_time = time.time()
            log_data = {
                "remote_address": request.META["REMOTE_ADDR"],
                "server_hostname": socket.gethostname(),
                "request_method": request.method,
                "request_path": request.get_full_path(),
            # Only logging "*/api/*" patterns
            if "/api/" in str(request.get_full_path()):
                req_body = json.loads(request.body.decode("utf-8")) if request.body else {}
                log_data["request_body"] = req_body
            response = self.get_response(request)
            if response and response["content-type"] == "application/json":
                response_body = json.loads(response.content.decode("utf-8"))
                log_data["response_body"] = response_body
            log_data["run_time"] = time.time() - start_time
            return response
        # Log unhandled exceptions as well
        def process_exception(self, request, exception):
                raise exception
            except Exception as e:
                request_logger.exception("Unhandled Exception: " + str(e))
            return exception

    Here we are logging only requests with /api/ in its path. All the processing is done in __call__ method.
    Note: Do add in middleware folder.

  • Activate the middleware

    Activate the middleware by adding its path in MIDDLEWARE list in your Django’s application (here: last value in list is added):

        # Request Logger

    Replace <application> with your application name.