Django - ведение журнала ответов на каждый запрос

У меня есть API, построенный с использованием фреймворка Django. Мне нужно регистрировать следующие данные для каждого запроса, поступающего к API.

  1. Метод запроса
  2. Путь запроса
  3. Объект запроса
  4. Код статуса ответа
  5. Задержка ответа (если возможно)

Я пробовал использовать сигнал request_finished, но он не приносит с собой объект ответа. Как я могу этого добиться?

Это работа для Django Middleware: https://docs.djangoproject.com/en/4.0/topics/http/middleware/

Когда вы устанавливаете "промежуточное ПО", вы получаете возможность вмешиваться до, во время и после обработки запроса, для всех запросов.

Как описано в ссылке документации, вам нужно создать класс Middleware, а затем сослаться на него в списке MIDDLEWARE в settings.

Middleware на основе классов достаточно прост, но более гибок (легко хранит состояние и имеет собственные методы). Что-то вроде этого:

class LogRequestsMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        start = time.perf_counter()
        response = self.get_response(request)
        end = time.perf_counter()
        self.log(request, start, end)
        return response

    def log(self, request, start, end):
        # log request.method, request.path_info, etc.
        # log end - start for duration

В этой настройке есть и другие хуки, но они вам не понадобятся. Даже если возникнет не пойманное исключение, Django обработает его и вернет объект ответа (из get_response) для чтения.

Имейте в виду, что это не тот же объект запроса, который вы получаете в представлении. Это экземпляр django.core.handlers.wsgi.WSGIRequest, но те значения, которые вы ищете, должны быть там.

Для расчета latency вы можете взять значения из time.perf_counter() как до, так и после обработки запроса в вашем методе __call__, а разницу считать длительностью:

elapsed = time.perf_counter()  # Includes time elapsed during sleep system-wide
duration = time.process_time()  # Process time not including sleep
Вернуться на верх