天天看點

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

錯誤報告

當你運作一個公開站點時,你應該始終關閉

DEBUG

設定。這會使你的伺服器運作得更快,也會防止惡意使用者看到由錯誤頁面展示的一些應用細節。

但是,運作在 

DEBUG

False

的情況下,你不會看到你的站點所生成的錯誤 – 每個人都隻能看到公開的錯誤頁面。你需要跟蹤部署的站點上的錯誤,是以可以配置Django來生成帶有錯誤細節的報告。

報告郵件

伺服器錯誤

DEBUG

False

的時候,無論什麼時候代碼産生了未處理的異常,并且出現了伺服器内部錯誤(HTTP狀态碼 500),Django 都會給

ADMINS

設定中的使用者發送郵件。 這會向管理者提供任何錯誤的及時通知。 

ADMINS

會得到一份錯誤的描述,完整的Python traceback,以及HTTP請求和導緻錯誤的詳細資訊。

注意

為了發送郵件,DJango需要一些設定來告訴它如何連接配接到郵件伺服器。最起碼,你需要指定

EMAIL_HOST

,可能需要

EMAIL_HOST_USER

EMAIL_HOST_PASSWORD

,盡管所需的其他設定可能也依賴于你的郵件伺服器的配置。郵件相關設定的完整清單請見

Django設定文檔

Django通常從

root@localhost

發送郵件。但是一些郵件提供商會拒收所有來自這個位址的郵件。修改

SERVER_EMAIL

設定可以使用不同的發信人位址。

将收信人的郵箱位址放入

ADMINS

設定中來激活這一行為。

另見

伺服器錯誤郵件使用日志架構來發送,是以你可以通過 

自定義你的日志配置

自定義這一行為。

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會為産生的異常記錄

完整的traceback

traceback 幀

的每個局部變量,以及

HttpRequest

屬性

然而,有時特定的消息類型十分敏感,并不适合跟蹤消息,比如使用者的密碼或者信用卡卡号。是以Django提供一套函數裝飾器,來幫助你控制需要在生産環境(也就是

DEBUG

False

的情況)中的錯誤報告中過濾的消息:

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

,

pw

cc

變量的值會在錯誤報告中隐藏并且使用星号(****) 來代替,雖然

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)

如果你的代碼中一個視圖接收到了可能帶有敏感資訊的,帶有

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_word

credit_card_number

POST參數的值會在錯誤報告中隐藏并且使用星号(****) 來代替,雖然

name

要想有順序地在錯誤報告中隐藏一個請求的所有POST 參數,不要向

sensitive_post_parameters

  裝飾器提供任何參數:

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

所有POST參數按順序被過濾出特定

django.contrib.auth.views

視圖的錯誤報告(

login

password_reset_confirm

password_change

add_view

auth

中的

user_change_password

),來防止像是使用者密碼這樣的敏感資訊的洩露。

自定義錯誤報告

所有

sensitive_variables()

  和

sensitive_post_parameters()

分别用敏感變量的名字向被裝飾的函數添加注解,以及用POST敏感參數的名字向

HttpRequest

對象添加注解,以便在錯誤産生時可以随後過濾掉報告中的敏感資訊。Django的預設錯誤包告過濾器

django.views.debug.SafeExceptionReporterFilter

會完成實際的過濾操作。

産生錯誤報告的時候,這個過濾器使用裝飾器的注解來将相應的值替換為星号 (****) 。如果你希望為你的整個站點覆寫或自定義這一預設的屬性,你需要定義你自己的過濾器類,并且通過

DEFAULT_EXCEPTION_REPORTER_FILTER

設定來讓Django使用它。

DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
           

你也可能會以更精細的方式來控制在提供的視圖中使用哪種過濾器,通過設定 

HttpRequest

exception_reporter_filter

屬性。

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

你的自定義過濾器類需要繼承自 

django.views.debug.SafeExceptionReporterFilter

,并且可能需要覆寫以下方法:

class

SafeExceptionReporterFilter

SafeExceptionReporterFilter.``is_active

(request)

如果其它方法中操作的過濾器已激活,傳回

True

。如果

DEBUG

False

,通常過濾器是激活的。

SafeExceptionReporterFilter.``get_request_repr

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

傳回過濾後的POST參數字典。通常它會把敏感參數的值以星号 (****)替換。

SafeExceptionReporterFilter.``get_traceback_frame_variables

(request, tb_frame)

傳回過濾後的,所提供traceback幀的局部變量的字典。通常它會把敏感變量的值以星号 (****)替換。

你也可以通過編寫自定義的

exception middleware

來建立自定義的錯誤報告。如果你編寫了自定義的錯誤處理器,模拟Django内建的錯誤處理器,隻在

DEBUG

False

時報告或記錄錯誤是個好主意。

譯者: Django 文檔協作翻譯小組 ,原文: Tracking code errors by email 本文以 CC BY-NC-SA 3.0 協定釋出,轉載請保留作者署名和文章出處。 人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。