django.request 记录器不适用于 get_object_or_404

django.request logger not working for get_object_or_404

我在 Django Rest Framework 中有 UserDetailsView 的代码。我正在使用 django 1.9 和 DRF 3。

class UserDetailsView(RetrieveUpdateAPIView):
    """
    API endpoint that allows a user to be viewed or edited.
    """
    serializer_class = UserDetailsSerializer
    permission_classes = (IsAuthenticated,)

    def get_object(self):
        pk = self.kwargs.get('pk', None)
        if not pk or (pk == str(self.request.user.pk)):
            return self.request.user
        else:
            try:
                return get_object_or_404(User, id=pk)
            except ValueError:
                return get_object_or_404(User, username=pk) 

我已经按照这些设置配置了我的 django 记录器。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'simple': {
            'format': '[%(levelname)s]  %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/backend_common.log',
            'maxBytes': 1024*1024*10,
            'backupCount': 10,
            'formatter': 'simple',
        },
        'request_handler': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/backend_requests.log',
            'maxBytes': 1024*1024*10,
            'backupCount': 10,
            'formatter': 'simple',
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
        }
    },
    'loggers': {
        '': {
            'handlers': ['default'],
            'propagate': True,
        },
        'django.request': {
            'handlers': ['request_handler', 'mail_admins'],
            'level': 'DEBUG',
            'propagate': False,
        }
    }
}

现在,理想情况下,所有 django 4xx、5xx 错误状态代码都应该记录到 backend_requests.log 文件中,除了由 get_object_or_404 产生的 404 状态之外。我认为由此视图产生的 404 错误也应该记录下来。非常感谢任何帮助。

这里其实有两个问题。

第一个是 Django 中的错误,即 fixed just a few days ago。记录 404 的代码 运行 有点太早了。下一个版本的 Django 将可以运行,您的 404 将如您所愿地被记录下来。

但是对于其他异常,问题如下。如果导致错误的异常冒泡到核心请求处理程序,Django 将记录错误。但是,如果视图或某些中间件捕获异常并进行处理,则 Django 代码的这一部分永远不会被调用。这就是 DRF:

的情况

REST framework's views handle various exceptions, and deal with returning appropriate error responses.

The handled exceptions are:

  • Subclasses of APIException raised inside REST framework.
  • Django's Http404 exception.
  • Django's PermissionDenied exception.

In each case, REST framework will return a response with an appropriate status code and content-type. The body of the response will include any additional details regarding the nature of the error.

因为 DRF 捕获异常并且 returns 是 Django 的响应对象,Django 将只呈现响应而不记录错误。这是有道理的——某些中间件可能会采用最初的 404 但 return 不同的响应(flatpage 中间件就是一个很好的例子)。

如果您想记录 DRF 处理的异常,您可以在 DRF 配置中指定您自己的 EXCEPTION_HANDLER,或者编写您自己的记录错误的中间件。

请注意,DRF 不处理 5xx 异常,这些异常仍应传播到 Django。即使现在也应该为您记录这些内容。