django.request记录器不适用于get_object_or_404

时间:2016-04-30 13:41:17

标签: django django-rest-framework django-logging

我在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错误也应该被记录下来。任何帮助都非常感谢。

1 个答案:

答案 0 :(得分:1)

这里实际上有两个问题。

第一个是Django中的一个错误,它是fixed just a few days ago。记录404s的代码运行有点太早了。 Django的下一个版本将正常工作,您的404将按照您的预期进行记录。

但是,对于其他例外,问题如下。如果导致它们的异常冒泡到核心请求处理程序,Django将记录错误。但是,如果视图或某些中间件捕获异常并处理它,那么Django代码的这部分永远不会被调用。 DRF发生了这种情况:

  

REST框架的视图处理各种异常,并处理返回适当的错误响应。

     

处理的例外情况是:

     
      
  • REST框架内引发的APIException子类。
  •   
  • Django的Http404例外。
  •   
  • Django的PermissionDenied例外。
  •   
     

在每种情况下,REST框架都将返回具有适当状态代码和内容类型的响应。回复正文将包含有关错误性质的任何其他详细信息。

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

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

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