# 錯誤報告
當你運行一個公開站點時,你應該始終關閉[`DEBUG`](../ref/settings.html#std:setting-DEBUG) 設置。這會使你的服務器運行得更快,也會防止惡意用戶看到由錯誤頁面展示的一些應用細節。
但是,運行在 [`DEBUG`](../ref/settings.html#std:setting-DEBUG)為`False`的情況下,你不會看到你的站點所生成的錯誤 -- 每個人都只能看到公開的錯誤頁面。你需要跟蹤部署的站點上的錯誤,所以可以配置Django來生成帶有錯誤細節的報告。
## 報告郵件
### 服務器錯誤
[`DEBUG`](../ref/settings.html#std:setting-DEBUG) 為 `False`的時候,無論什么時候代碼產生了未處理的異常,并且出現了服務器內部錯誤(HTTP狀態碼 500),Django 都會給[`ADMINS`](../ref/settings.html#std:setting-ADMINS)設置中的用戶發送郵件。 這會向管理員提供任何錯誤的及時通知。 [`ADMINS`](../ref/settings.html#std:setting-ADMINS)會得到一份錯誤的描述,完整的Python traceback,以及HTTP請求和導致錯誤的詳細信息。
注意
為了發送郵件,DJango需要一些設置來告訴它如何連接到郵件服務器。最起碼,你需要指定 [`EMAIL_HOST`](../ref/settings.html#std:setting-EMAIL_HOST) ,可能需要 [`EMAIL_HOST_USER`](../ref/settings.html#std:setting-EMAIL_HOST_USER) 和[`EMAIL_HOST_PASSWORD`](../ref/settings.html#std:setting-EMAIL_HOST_PASSWORD),盡管所需的其他設置可能也依賴于你的郵件服務器的配置。郵件相關設置的完整列表請見 [_Django設置文檔_](../ref/settings.html)。
Django通常從[root@localhost](mailto:root%40localhost)發送郵件。但是一些郵件提供商會拒收所有來自這個地址的郵件。修改[`SERVER_EMAIL`](../ref/settings.html#std:setting-SERVER_EMAIL)設置可以使用不同的發信人地址。
將收信人的郵箱地址放入[`ADMINS`](../ref/settings.html#std:setting-ADMINS)設置中來激活這一行為。
另見
服務器錯誤郵件使用日志框架來發送,所以你可以通過 [_自定義你的日志配置_](../topics/logging.html)自定義這一行為。
### 404錯誤
也可以配置Django來發送關于死鏈的郵件(404"找不到頁面"錯誤)。Django在以下情況發送404錯誤的郵件:
* [`DEBUG`](../ref/settings.html#std:setting-DEBUG)為 `False`;
* 你的[`MIDDLEWARE_CLASSES`](../ref/settings.html#std:setting-MIDDLEWARE_CLASSES) 設置含有 [`django.middleware.common.BrokenLinkEmailsMiddleware`](../ref/middleware.html#django.middleware.common.BrokenLinkEmailsMiddleware "django.middleware.common.BrokenLinkEmailsMiddleware")。
如果符合這些條件,無論什么時候你的代碼產生404錯誤,并且請求帶有referer, Django 都會給[`MANAGERS`](../ref/settings.html#std:setting-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`](../ref/middleware.html#django.middleware.common.BrokenLinkEmailsMiddleware "django.middleware.common.BrokenLinkEmailsMiddleware") 必須出現在其它攔截404錯誤的中間件之前,比如 [`LocaleMiddleware`](../ref/middleware.html#django.middleware.locale.LocaleMiddleware "django.middleware.locale.LocaleMiddleware") 或者 [`FlatpageFallbackMiddleware`](../ref/contrib/flatpages.html#django.contrib.flatpages.middleware.FlatpageFallbackMiddleware "django.contrib.flatpages.middleware.FlatpageFallbackMiddleware")。把它放在你的[`MIDDLEWARE_CLASSES`](../ref/settings.html#std:setting-MIDDLEWARE_CLASSES)設置的最上面。
你可以通過調整[`IGNORABLE_404_URLS`](../ref/settings.html#std:setting-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`](../ref/middleware.html#django.middleware.common.BrokenLinkEmailsMiddleware "django.middleware.common.BrokenLinkEmailsMiddleware") 的行為(比如忽略來自web爬蟲的請求),你應該繼承它并覆寫它的方法。
另見
404錯誤使用日志框架來記錄。通常,日志記錄會被忽略,但是你可以通過編寫合適的處理器和[_配置日志_](../topics/logging.html),將它們用于錯誤報告。
## 過濾錯誤報告
### 過濾敏感的信息
錯誤報告對錯誤的調試及其有用,所以對于這些錯誤,通常它會盡可能多的記錄下相關信息。例如,通常DJango會為產生的異常記錄[完整的traceback](http://en.wikipedia.org/wiki/Stack_trace),[traceback 幀](http://en.wikipedia.org/wiki/Stack_frame)的每個局部變量,以及[`HttpRequest`](../ref/request-response.html#django.http.HttpRequest "django.http.HttpRequest")的[_屬性_](../ref/request-response.html#httprequest-attributes)。
然而,有時特定的消息類型十分敏感,并不適合跟蹤消息,比如用戶的密碼或者信用卡卡號。所以Django提供一套函數裝飾器,來幫助你控制需要在生產環境(也就是[`DEBUG`](../ref/settings.html#std:setting-DEBUG)為 `False`的情況)中的錯誤報告中過濾的消息:[`sensitive_variables()`](#django.views.decorators.debug.sensitive_variables "django.views.decorators.debug.sensitive_variables")和[`sensitive_post_parameters()`](#django.views.decorators.debug.sensitive_post_parameters "django.views.decorators.debug.sensitive_post_parameters")。
`sensitive_variables`(_*variables_)[[source]](../_modules/django/views/decorators/debug.html#sensitive_variables)
如果你的代碼中一個函數(視圖或者常規的回調)使用可能含有敏感信息的局部變量,你可能需要使用`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]](../_modules/django/views/decorators/debug.html#sensitive_post_parameters)
如果你的代碼中一個視圖接收到了可能帶有敏感信息的,帶有[`POST 參數`](../ref/request-response.html#django.http.HttpRequest.POST "django.http.HttpRequest.POST")的[`HttpRequest`](../ref/request-response.html#django.http.HttpRequest "django.http.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`](../topics/auth/default.html#module-django.contrib.auth.views "django.contrib.auth.views") 視圖的錯誤報告(`login`, `password_reset_confirm`, `password_change`, `add_view` 和`auth`中的`user_change_password`),來防止像是用戶密碼這樣的敏感信息的泄露。
### 自定義錯誤報告
所有[`sensitive_variables()`](#django.views.decorators.debug.sensitive_variables "django.views.decorators.debug.sensitive_variables") 和 [`sensitive_post_parameters()`](#django.views.decorators.debug.sensitive_post_parameters "django.views.decorators.debug.sensitive_post_parameters")分別用敏感變量的名字向被裝飾的函數添加注解,以及用POST敏感參數的名字向`HttpRequest`對象添加注解,以便在錯誤產生時可以隨后過濾掉報告中的敏感信息。Django的默認錯誤包告過濾器[`django.views.debug.SafeExceptionReporterFilter`](#django.views.debug.SafeExceptionReporterFilter "django.views.debug.SafeExceptionReporterFilter")會完成實際的過濾操作。
產生錯誤報告的時候,這個過濾器使用裝飾器的注解來將相應的值替換為星號 (<cite>**********</cite>) 。如果你希望為你的整個站點覆寫或自定義這一默認的屬性,你需要定義你自己的過濾器類,并且通過[`DEFAULT_EXCEPTION_REPORTER_FILTER`](../ref/settings.html#std:setting-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`](#django.views.debug.SafeExceptionReporterFilter "django.views.debug.SafeExceptionReporterFilter"),并且可能需要覆寫以下方法:
_class _`SafeExceptionReporterFilter`[[source]](../_modules/django/views/debug.html#SafeExceptionReporterFilter)
`SafeExceptionReporterFilter.``is_active`(_request_)[[source]](../_modules/django/views/debug.html#SafeExceptionReporterFilter.is_active)
如果其它方法中操作的過濾器已激活,返回`True`。如果 [`DEBUG`](../ref/settings.html#std:setting-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()`](#django.views.debug.SafeExceptionReporterFilter.get_post_parameters "django.views.debug.SafeExceptionReporterFilter.get_post_parameters").
`SafeExceptionReporterFilter.``get_post_parameters`(_request_)[[source]](../_modules/django/views/debug.html#SafeExceptionReporterFilter.get_post_parameters)
返回過濾后的POST參數字典。通常它會把敏感參數的值以星號 (<cite>**********</cite>)替換。
`SafeExceptionReporterFilter.``get_traceback_frame_variables`(_request_, _tb_frame_)[[source]](../_modules/django/views/debug.html#SafeExceptionReporterFilter.get_traceback_frame_variables)
返回過濾后的,所提供traceback幀的局部變量的字典。通常它會把敏感變量的值以星號 (<cite>**********</cite>)替換。
另見
你也可以通過編寫自定義的[_exception middleware_](../topics/http/middleware.html#exception-middleware)來建立自定義的錯誤報告。如果你編寫了自定義的錯誤處理器,模擬Django內建的錯誤處理器,只在[`DEBUG`](../ref/settings.html#std:setting-DEBUG) 為 `False`時報告或記錄錯誤是個好主意。
> 譯者:[Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html),原文:[Tracking code errors by email](https://docs.djangoproject.com/en/1.8/howto/error-reporting/)。
>
> 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 協議發布,轉載請保留作者署名和文章出處。
>
> [Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html)人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。
- 新手入門
- 從零開始
- 概覽
- 安裝
- 教程
- 第1部分:模型
- 第2部分:管理站點
- 第3部分:視圖和模板
- 第4部分:表單和通用視圖
- 第5部分:測試
- 第6部分:靜態文件
- 高級教程
- 如何編寫可重用的應用
- 為Django編寫首個補丁
- 模型層
- 模型
- 模型語法
- 元選項
- 模型類
- 查詢集
- 執行查詢
- 查找表達式
- 模型的實例
- 實例方法
- 訪問關聯對象
- 遷移
- 模式編輯器
- 編寫遷移
- 高級
- 管理器
- 原始的SQL查詢
- 聚合
- 多數據庫
- 自定義查找
- 條件表達式
- 數據庫函數
- 其它
- 遺留的數據庫
- 提供初始數據
- 優化數據庫訪問
- 視圖層
- 基礎
- URL配置
- 視圖函數
- 快捷函數
- 裝飾器
- 參考
- 內建的視圖
- TemplateResponse 對象
- 文件上傳
- 概覽
- File 對象
- 儲存API
- 管理文件
- 自定義存儲
- 基于類的視圖
- 概覽
- 內建顯示視圖
- 內建編輯視圖
- API參考
- 分類索引
- 高級
- 生成 CSV
- 生成 PDF
- 中間件
- 概覽
- 內建的中間件類
- 模板層
- 基礎
- 面向設計師
- 語言概覽
- 人性化
- 面向程序員
- 表單
- 基礎
- 概覽
- 表單API
- 內建的Widget
- 高級
- 整合媒體
- 開發過程
- 設置
- 概覽
- 應用程序
- 異常
- 概覽
- django-admin 和 manage.py
- 添加自定義的命令
- 測試
- 介紹
- 部署
- 概述
- WSGI服務器
- 部署靜態文件
- 通過email追蹤代碼錯誤
- Admin
- 管理操作
- 管理文檔生成器
- 安全
- 安全概述
- 說明Django中的安全問題
- 點擊劫持保護
- 加密簽名
- 國際化和本地化
- 概述
- 本地化WEB UI格式化輸入
- “本地特色”
- 常見的網站應用工具
- 認證
- 概覽
- 使用認證系統
- 密碼管理
- 日志
- 分頁
- 會話
- 數據驗證
- 其它核心功能
- 按需內容處理
- 重定向
- 信號
- 系統檢查框架