2016-04-30 72 views
1

我在Django Rest Framework中有UserDetailsView的這段代碼。我正在使用django 1.9和DRF 3.django.request記錄器不適用於get_object_or_404

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文件,他們除了404個狀態從get_object_or_404產生。我認爲這個視圖導致的404錯誤也應該被記錄下來。任何幫助,高度讚賞。

+0

'get_object_or_404'不會引發異常。這樣做,它不會寫入日誌。 –

+0

@EdwinLunando你錯了。 'get_object_or_404'確實會引發一個異常:'Http404'。 – RodrigoDela

+0

你提供的日誌配置工作正如我所料......你能否確認你的客戶端實際上是在接收一個HTTP 404響應而不是別的東西(例如403,500)? – solarissmoke

回答

0

這裏實際上有兩個問題。

第一個是Django中的一個bug,它是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,或編寫自己的記錄錯誤的中間件。

請注意,5xx異常不由DRF處理,它們仍應傳播到Django。即使現在,這些應該也會被記錄下來。

相關問題