django 1.8 官方文檔翻譯:6-6-5 錯誤報告

錯誤報告

當你運行一個公開站點時,你應該始終關閉DEBUG 設置。這會使你的服務器運行得更快,也會防止惡意用戶看到由錯誤頁面展現的一些應用細節。php

可是,運行在 DEBUGFalse的狀況下,你不會看到你的站點所生成的錯誤 -- 每一個人都只能看到公開的錯誤頁面。你須要跟蹤部署的站點上的錯誤,因此能夠配置Django來生成帶有錯誤細節的報告。html

報告郵件

服務器錯誤

DEBUGFalse的時候,不管何時代碼產生了未處理的異常,而且出現了服務器內部錯誤(HTTP狀態碼 500),Django 都會給ADMINS設置中的用戶發送郵件。 這會向管理員提供任何錯誤的及時通知。 ADMINS會獲得一份錯誤的描述,完整的Python traceback,以及HTTP請求和致使錯誤的詳細信息。python

注意web

爲了發送郵件,DJango須要一些設置來告訴它如何鏈接到郵件服務器。最起碼,你須要指定 EMAIL_HOST ,可能須要 EMAIL_HOST_USEREMAIL_HOST_PASSWORD,儘管所需的其餘設置可能也依賴於你的郵件服務器的配置。郵件相關設置的完整列表請見 _Django設置文檔_正則表達式

Django一般從root@localhost發送郵件。可是一些郵件提供商會拒收全部來自這個地址的郵件。修改SERVER_EMAIL設置可使用不一樣的發信人地址。django

將收信人的郵箱地址放入ADMINS設置中來激活這一行爲。瀏覽器

另見服務器

服務器錯誤郵件使用日誌框架來發送,因此你能夠經過 _自定義你的日誌配置_自定義這一行爲。app

404錯誤

也能夠配置Django來發送關於死鏈的郵件(404"找不到頁面"錯誤)。Django在如下狀況發送404錯誤的郵件:框架

若是符合這些條件,不管何時你的代碼產生404錯誤,而且請求帶有referer, Django 都會給MANAGERS中的用戶發送郵件。 (It doesn’t bother to email for 404s that don’t have a referer – those are usually just people typing in broken URLs or broken Web ‘bots).

注意

BrokenLinkEmailsMiddleware 必須出如今其它攔截404錯誤的中間件以前,好比 LocaleMiddleware 或者 FlatpageFallbackMiddleware。把它放在你的MIDDLEWARE_CLASSES設置的最上面。

你能夠經過調整IGNORABLE_404_URLS設置,告訴Django中止報告特定的404錯誤。它應該爲一個元組,含有編譯後的正則表達式對象。例如:

import re
IGNORABLE_404_URLS = (
    re.compile(r'\.(php|cgi)$'),
    re.compile(r'^/phpmyadmin/'),
)

在這個例子中,任何以.php 或者.cgi結尾URL的404錯誤都_不會_報告。任何以/phpmyadmin/開頭的URL也不會。

下面的例子展現瞭如何排除一些瀏覽器或爬蟲常常請求的經常使用URL:

import re
IGNORABLE_404_URLS = (
    re.compile(r'^/apple-touch-icon.*\.png$'),
    re.compile(r'^/favicon\.ico$'),
    re.compile(r'^/robots\.txt$'),
)

(要注意這些是正則表達式,因此須要在句號前面添加反斜線來對它轉義。)

若是你打算進一步自定義django.middleware.common.BrokenLinkEmailsMiddleware 的行爲(好比忽略來自web爬蟲的請求),你應該繼承它並覆寫它的方法。

另見

404錯誤使用日誌框架來記錄。一般,日誌記錄會被忽略,可是你能夠經過編寫合適的處理器和_配置日誌_,將它們用於錯誤報告。

過濾錯誤報告

過濾敏感的信息

錯誤報告對錯誤的調試及其有用,因此對於這些錯誤,一般它會盡量多的記錄下相關信息。例如,一般DJango會爲產生的異常記錄完整的tracebacktraceback 幀的每一個局部變量,以及HttpRequest_屬性_

然而,有時特定的消息類型十分敏感,並不適合跟蹤消息,好比用戶的密碼或者信用卡卡號。因此Django提供一套函數裝飾器,來幫助你控制須要在生產環境(也就是DEBUGFalse的狀況)中的錯誤報告中過濾的消息:sensitive_variables()sensitive_post_parameters()

sensitive_variables(_*variables_)[source]

若是你的代碼中一個函數(視圖或者常規的回調)使用可能含有敏感信息的局部變量,你可能須要使用sensitive_variables 裝飾器,來阻止錯誤報告包含這些變量的值。

from django.views.decorators.debug import sensitive_variables

@sensitive_variables('user', 'pw', 'cc')
def process_info(user):
    pw = user.pass_word
    cc = user.credit_card_number
    name = user.name
    ...

在上面的例子中,user, pwcc 變量的值會在錯誤報告中隱藏而且使用星號(<cite>**</cite>) 來代替,雖然name 變量的值會公開。

要想有順序地在錯誤報告中隱藏一個函數的全部局部變量,不要向sensitive_variables 裝飾器提供任何參數:

@sensitive_variables()
def my_function():
    ...

使用多個裝飾器的時候

若是你想要隱藏的變量也是一個函數的參數(例如,下面例子中的user),而且被裝飾的函數有多個裝飾器,你須要確保將@sensitive_variables 放在裝飾器鏈的頂端。這種方法也會隱藏函數參數,儘管它經過其它裝飾器傳遞:

@sensitive_variables('user', 'pw', 'cc')
@some_decorator
@another_decorator
def process_info(user):
    ...

sensitive_post_parameters(_*parameters_)[source]

若是你的代碼中一個視圖接收到了可能帶有敏感信息的,帶有POST 參數HttpRequest對象,你可能須要使用sensitive_post_parameters  裝飾器,來阻止錯誤報告包含這些參數的值。

from django.views.decorators.debug import sensitive_post_parameters

@sensitive_post_parameters('pass_word', 'credit_card_number')
def record_user_profile(request):
    UserProfile.create(user=request.user,
                       password=request.POST['pass_word'],
                       credit_card=request.POST['credit_card_number'],
                       name=request.POST['name'])
    ...

在上面的例子中,pass_wordcredit_card_number POST參數的值會在錯誤報告中隱藏而且使用星號(<cite>**</cite>) 來代替,雖然name變量的值會公開。

要想有順序地在錯誤報告中隱藏一個請求的全部POST 參數,不要向sensitive_post_parameters  裝飾器提供任何參數:

@sensitive_post_parameters()
def my_view(request):
    ...

全部POST參數按順序被過濾出特定django.contrib.auth.views 視圖的錯誤報告(login, password_reset_confirm, password_change, add_viewauth中的user_change_password),來防止像是用戶密碼這樣的敏感信息的泄露。

自定義錯誤報告

全部sensitive_variables()  和 sensitive_post_parameters()分別用敏感變量的名字向被裝飾的函數添加註解,以及用POST敏感參數的名字向HttpRequest對象添加註解,以便在錯誤產生時能夠隨後過濾掉報告中的敏感信息。Django的默認錯誤包告過濾器django.views.debug.SafeExceptionReporterFilter會完成實際的過濾操做。
產生錯誤報告的時候,這個過濾器使用裝飾器的註解來將相應的值替換爲星號 (<cite>**</cite>) 。若是你但願爲你的整個站點覆寫或自定義這一默認的屬性,你須要定義你本身的過濾器類,而且經過DEFAULT_EXCEPTION_REPORTER_FILTER 設置來讓Django使用它。

DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'

你也可能會以更精細的方式來控制在提供的視圖中使用哪一種過濾器,經過設置 HttpRequestexception_reporter_filter屬性。

def my_view(request):
    if request.user.is_authenticated():
        request.exception_reporter_filter = CustomExceptionReporterFilter()
    ...

你的自定義過濾器類須要繼承自 django.views.debug.SafeExceptionReporterFilter,而且可能須要覆寫如下方法:

_class _SafeExceptionReporterFilter[source]

SafeExceptionReporterFilter.`is_active`(_request_)[source]

若是其它方法中操做的過濾器已激活,返回True。若是 DEBUGFalse,一般過濾器是激活的。

SafeExceptionReporterFilter.`get_request_repr`(_request_)

Returns the representation string of the request object, that is, the value that would be returned by repr(request), except it uses the filtered dictionary of POST parameters as determined by SafeExceptionReporterFilter.get_post_parameters().

SafeExceptionReporterFilter.`get_post_parameters`(_request_)[source]

返回過濾後的POST參數字典。一般它會把敏感參數的值以星號 (<cite>**</cite>)替換。

SafeExceptionReporterFilter.`get_traceback_frame_variables`(_request_, _tb_frame_)[source]

返回過濾後的,所提供traceback幀的局部變量的字典。一般它會把敏感變量的值以星號 (<cite>**</cite>)替換。

另見

你也能夠經過編寫自定義的_exception middleware_來創建自定義的錯誤報告。若是你編寫了自定義的錯誤處理器,模擬Django內建的錯誤處理器,只在DEBUGFalse時報告或記錄錯誤是個好主意。

譯者:Django 文檔協做翻譯小組,原文:Tracking code errors by email

本文以 CC BY-NC-SA 3.0 協議發佈,轉載請保留做者署名和文章出處。

Django 文檔協做翻譯小組人手緊缺,有興趣的朋友能夠加入咱們,徹底公益性質。交流羣:467338606。

相關文章
相關標籤/搜索