當你運行一個公開站點時,你應該始終關閉DEBUG
設置。這會使你的服務器運行得更快,也會防止惡意用戶看到由錯誤頁面展現的一些應用細節。php
可是,運行在 DEBUG
爲False
的狀況下,你不會看到你的站點所生成的錯誤 -- 每一個人都只能看到公開的錯誤頁面。你須要跟蹤部署的站點上的錯誤,因此能夠配置Django來生成帶有錯誤細節的報告。html
DEBUG
爲 False
的時候,不管何時代碼產生了未處理的異常,而且出現了服務器內部錯誤(HTTP狀態碼 500),Django 都會給ADMINS
設置中的用戶發送郵件。 這會向管理員提供任何錯誤的及時通知。 ADMINS
會獲得一份錯誤的描述,完整的Python traceback,以及HTTP請求和致使錯誤的詳細信息。python
注意web
爲了發送郵件,DJango須要一些設置來告訴它如何鏈接到郵件服務器。最起碼,你須要指定 EMAIL_HOST
,可能須要 EMAIL_HOST_USER
和EMAIL_HOST_PASSWORD
,儘管所需的其餘設置可能也依賴於你的郵件服務器的配置。郵件相關設置的完整列表請見 _Django設置文檔_。正則表達式
Django一般從root@localhost發送郵件。可是一些郵件提供商會拒收全部來自這個地址的郵件。修改SERVER_EMAIL
設置可使用不一樣的發信人地址。django
將收信人的郵箱地址放入ADMINS
設置中來激活這一行爲。瀏覽器
另見服務器
服務器錯誤郵件使用日誌框架來發送,因此你能夠經過 _自定義你的日誌配置_自定義這一行爲。app
也能夠配置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
變量的值會在錯誤報告中隱藏而且使用星號(<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_word
和 credit_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_view
和auth
中的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'
你也可能會以更精細的方式來控制在提供的視圖中使用哪一種過濾器,經過設置 HttpRequest
的exception_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
。若是 DEBUG
爲False
,一般過濾器是激活的。
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內建的錯誤處理器,只在DEBUG
爲 False
時報告或記錄錯誤是個好主意。
譯者:Django 文檔協做翻譯小組,原文:Tracking code errors by email。
本文以 CC BY-NC-SA 3.0 協議發佈,轉載請保留做者署名和文章出處。
Django 文檔協做翻譯小組人手緊缺,有興趣的朋友能夠加入咱們,徹底公益性質。交流羣:467338606。