Как регистрировать все ошибки, связанные с запросом API в Django Rest Framework, вместе с несколькими полями в CSV-файле?

Я хочу записывать любой тип ошибки, возникающей во время запроса API в Django Rest Framework, в CSV-файл, включая сообщение об ошибке вместе с дополнительными данными, такими как имя пользователя, ip-адрес пользователя, URL-адрес и т.д. Я также хочу зафиксировать ошибки, которые возникают до перехода к просмотру (например, ошибки, связанные с JWT). Я пытался использовать для этого промежуточное программное обеспечение, но проблема заключалась в том, что некоторые ответы отображались неправильно, и даже после ручного отображения они по-прежнему приводили к ошибкам. Я был бы признателен, если бы вы предложили решение.

Приведенный ниже код - это промежуточное программное обеспечение, которое я пытался использовать. У меня нет проблем с регистрацией ошибок, возникающих внутри представления, потому что, если бы я хотел регистрировать ошибки только в представлении, я мог бы использовать декораторы или создать пользовательский APIView. Однако то, что я ищу, - это способ регистрировать ошибки любого типа, даже те, которые возникают вне поля зрения.

class ErrorLogMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.filename = settings.ERROR_LOG_PATH
        self.fieldnames = ["Username", "IP", "User Agent", "Date/Time", "Time Interval", "Query", "Message", "URL"]

    def __call__(self, request):
        if not exists(self.filename):
            with open(self.filename, "a", newline="", encoding="utf-8") as csvfile:
                writer = DictWriter(csvfile, fieldnames=self.fieldnames)
                writer.writeheader()

        before = time()
        try:
            response = self.get_response(request)

            if response.status_code != 200:
                if hasattr(response, "render"):
                    if not response.is_rendered:
                        response.render()

                error = None
                if hasattr(response, "data"):
                    error = response.data
                else:
                    html_content = response.content.decode("utf-8")
                    error = html_content.split("</title>")[0].split("<title>")[1]

                self.submit_error(request, before, error)

            return response

        except Exception as e:
            self.submit_error(request, before, e)
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    def submit_error(self, request, before, error):
        after = time()
        query = ""

        for dic in connection.queries:
            query += f"{dic['sql']}\n"

        new_error_log = {
            "Username": request.user.username,
            "IP": get_user_ip(request),
            "User Agent": request.META.get("HTTP_USER_AGENT"),
            "Date/Time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "Time Interval": after - before,
            "Query": query,
            "Message": str(error),
            "URL": request.get_full_path()
        }

        with open(self.filename, "a", newline="", encoding="utf-8") as csvfile:
            writer = DictWriter(csvfile, fieldnames=self.fieldnames)
            writer.writerow(new_error_log)

ошибка: содержимое ответа должно быть отрисовано до того, как к нему можно будет получить доступ

Вы можете использовать logging для регистрации запросов django api и добавить пользовательское промежуточное программное обеспечение или обработчик исключений, чтобы при необходимости изменить содержимое https://docs.djangoproject.com/en/5.1/howto/logging/

Вернуться на верх