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/request_log.py
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 request_logger.info(msg=log_data) return response # Log unhandled exceptions as well def process_exception(self, request, exception): try: 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__init__.py
inmiddleware
folder. -
Activate the middleware
Activate the middleware by adding its path in
MIDDLEWARE
list in your Django’s applicationsettings.py
(here: last value in list is added):MIDDLEWARE = [ ... "django.contrib.messages.middleware.MessageMiddleware", # Request Logger "<application>.middleware.request_log.RequestLogMiddleware", ]
Replace
<application>
with your application name.