記錄

Django 的記錄模組擴充了 Python 的內建 logging

記錄的設定是 Django 一般 django.setup() 函數的一部分,因此除非明確停用,否則它總是可用的。

Django 的預設記錄設定

預設情況下,Django 使用 Python 的 logging.config.dictConfig 格式

預設記錄條件

預設記錄條件的完整設定如下:

DEBUGTrue

  • django 記錄器會將 django 階層(django.server 除外)中 INFO 級別或更高的訊息傳送到主控台。

DEBUGFalse

  • django 記錄器會將 django 階層(django.server 除外)中 ERRORCRITICAL 級別的訊息傳送到 AdminEmailHandler

DEBUG 的值無關

  • django.server 記錄器會將 INFO 級別或更高的訊息傳送到主控台。

除了 django.server 之外的所有記錄器都會將記錄傳播到其父級,一直到根 django 記錄器。consolemail_admins 處理常式會附加到根記錄器,以提供上述行為。

Python 自己的預設會將 WARNING 級別及更高的記錄傳送到主控台。

預設記錄定義

Django 的預設記錄設定繼承了 Python 的預設值。它以 django.utils.log.DEFAULT_LOGGING 的形式提供,並定義在 django/utils/log.py

{
    "version": 1,
    "disable_existing_loggers": False,
    "filters": {
        "require_debug_false": {
            "()": "django.utils.log.RequireDebugFalse",
        },
        "require_debug_true": {
            "()": "django.utils.log.RequireDebugTrue",
        },
    },
    "formatters": {
        "django.server": {
            "()": "django.utils.log.ServerFormatter",
            "format": "[{server_time}] {message}",
            "style": "{",
        }
    },
    "handlers": {
        "console": {
            "level": "INFO",
            "filters": ["require_debug_true"],
            "class": "logging.StreamHandler",
        },
        "django.server": {
            "level": "INFO",
            "class": "logging.StreamHandler",
            "formatter": "django.server",
        },
        "mail_admins": {
            "level": "ERROR",
            "filters": ["require_debug_false"],
            "class": "django.utils.log.AdminEmailHandler",
        },
    },
    "loggers": {
        "django": {
            "handlers": ["console", "mail_admins"],
            "level": "INFO",
        },
        "django.server": {
            "handlers": ["django.server"],
            "level": "INFO",
            "propagate": False,
        },
    },
}

請參閱 設定記錄,以了解如何補充或取代此預設記錄設定。

Django 記錄擴充

Django 提供許多公用程式來處理 Web 伺服器環境中記錄的特殊需求。

記錄器

Django 提供數個內建記錄器。

django

django 具名記錄器階層中訊息的父記錄器。 Django 不會使用此名稱發布訊息。相反地,它會使用下列其中一個記錄器。

django.request

記錄與處理請求相關的訊息。 5XX 回應會以 ERROR 訊息的形式提出;4XX 回應會以 WARNING 訊息的形式提出。記錄到 django.security 記錄器的請求不會記錄到 django.request

此記錄器的訊息具有以下額外內容

  • status_code:與請求相關聯的 HTTP 回應碼。

  • request:產生記錄訊息的請求物件。

django.server

記錄與 runserver 命令叫用的伺服器接收的請求相關的訊息。 HTTP 5XX 回應會記錄為 ERROR 訊息,4XX 回應會記錄為 WARNING 訊息,其他所有內容都會記錄為 INFO

此記錄器的訊息具有以下額外內容

  • status_code:與請求相關聯的 HTTP 回應碼。

  • request:產生記錄訊息的請求物件(socket.socket)。

django.template

記錄與轉譯樣板相關的訊息。

  • 遺失的內容變數會記錄為 DEBUG 訊息。

django.db.backends

記錄與程式碼和資料庫互動相關的訊息。例如,請求執行的每個應用程式層級 SQL 陳述式都會以 DEBUG 級別記錄到此記錄器。

此記錄器的訊息具有以下額外內容

  • duration:執行 SQL 陳述式所花費的時間。

  • sql:已執行的 SQL 陳述式。

  • params:在 SQL 呼叫中使用的參數。

  • alias:在 SQL 呼叫中使用的資料庫別名。

基於效能考量,只有在 settings.DEBUG 設定為 True 時,才會啟用 SQL 記錄,而不論安裝的記錄層級或處理常式為何。

此記錄不包含架構層級的初始化(例如 SET TIMEZONE)。如果您想檢視所有資料庫查詢,請開啟資料庫中的查詢記錄。

django.utils.autoreload

記錄與執行 Django 開發伺服器期間自動重新載入程式碼相關的訊息。此記錄器會在偵測到原始碼檔案中的修改時產生 INFO 訊息,並且在檔案系統檢查和事件訂閱程序期間可能會產生 WARNING 訊息。

django.contrib.auth

在 Django 4.2.16 中新增。

記錄與 django.contrib.auth 相關的訊息,特別是在成功提交 PasswordResetForm 但由於郵件傳送例外狀況而無法傳遞密碼重設電子郵件時,會產生 ERROR 訊息。

django.contrib.gis

記錄與 GeoDjango 在不同時間點相關的訊息:在載入外部地理空間程式庫 (GEOS、GDAL 等) 期間,以及回報錯誤時。每個 ERROR 記錄都包含擷取的例外狀況和相關的內容資料。

django.dispatch

此記錄器用於 訊號 中,特別是在 Signal 類別中,以回報將訊號分派至已連線的接收器時發生的問題。ERROR 記錄包含擷取的例外狀況作為 exc_info,並新增以下額外內容

  • receiver:接收器的名稱。

  • err:呼叫接收器時發生的例外狀況。

django.security.*

安全記錄器將接收任何發生 SuspiciousOperation 和其他與安全相關錯誤時的訊息。每個安全錯誤子類型都有一個子記錄器,包括所有 SuspiciousOperation。記錄事件的層級取決於異常的處理位置。大多數事件都記錄為警告,而任何到達 WSGI 處理器的 SuspiciousOperation 都會記錄為錯誤。例如,當來自用戶端的請求中包含不符合 ALLOWED_HOSTS 的 HTTP Host 標頭時,Django 將返回 400 響應,並且錯誤訊息將記錄到 django.security.DisallowedHost 記錄器。

這些記錄事件預設會到達 django 記錄器,當 DEBUG=False 時,它會將錯誤事件郵寄給管理員。由於 SuspiciousOperation 而導致 400 響應的請求將不會記錄到 django.request 記錄器,而只會記錄到 django.security 記錄器。

若要關閉特定類型的 SuspiciousOperation,您可以按照以下範例覆寫該特定記錄器

LOGGING = {
    # ...
    "handlers": {
        "null": {
            "class": "logging.NullHandler",
        },
    },
    "loggers": {
        "django.security.DisallowedHost": {
            "handlers": ["null"],
            "propagate": False,
        },
    },
    # ...
}

其他非基於 SuspiciousOperationdjango.security 記錄器包括

django.db.backends.schema

記錄在資料庫結構變更期間,由 遷移框架 執行的 SQL 查詢。請注意,它不會記錄由 RunPython 執行的查詢。此記錄器的訊息在其額外上下文中包含 paramssql(但與 django.db.backends 不同,不包含持續時間)。這些值與 django.db.backends 中說明的含義相同。

django.contrib.sessions

記錄與 工作階段框架 相關的訊息。

處理器

除了 Python logging 模組提供的那些 之外,Django 還提供一個記錄處理器。

class AdminEmailHandler(include_html=False, email_backend=None, reporter_class=None)[原始碼]

此處理器會向網站的 ADMINS 發送電子郵件,用於接收到的每個記錄訊息。

如果記錄包含 request 屬性,則電子郵件中會包含請求的完整詳細資訊。如果用戶端的 IP 位址位於 INTERNAL_IPS 設定中,則電子郵件主旨會包含「內部 IP」字樣;否則,它會包含「外部 IP」。

如果記錄包含堆疊追蹤資訊,則電子郵件中會包含該堆疊追蹤。

AdminEmailHandlerinclude_html 引數用於控制追蹤電子郵件是否包含 HTML 附件,其中包含如果 DEBUGTrue 時將產生的除錯網頁完整內容。若要在組態中設定此值,請將其包含在 django.utils.log.AdminEmailHandler 的處理器定義中,如下所示

"handlers": {
    "mail_admins": {
        "level": "ERROR",
        "class": "django.utils.log.AdminEmailHandler",
        "include_html": True,
    },
}

使用 AdminEmailHandler 時,請注意記錄的安全性影響

透過設定 AdminEmailHandleremail_backend 引數,可以覆寫處理器正在使用的電子郵件後端,如下所示

"handlers": {
    "mail_admins": {
        "level": "ERROR",
        "class": "django.utils.log.AdminEmailHandler",
        "email_backend": "django.core.mail.backends.filebased.EmailBackend",
    },
}

預設情況下,將使用 EMAIL_BACKEND 中指定的電子郵件後端的執行個體。

AdminEmailHandlerreporter_class 引數允許提供 django.views.debug.ExceptionReporter 子類別,以自訂電子郵件內文中傳送的追蹤文字。您可以提供您想要使用的類別的字串匯入路徑,如下所示

"handlers": {
    "mail_admins": {
        "level": "ERROR",
        "class": "django.utils.log.AdminEmailHandler",
        "include_html": True,
        "reporter_class": "somepackage.error_reporter.CustomErrorReporter",
    },
}
send_mail(subject, message, *args, **kwargs)[原始碼]

向管理員使用者傳送電子郵件。若要自訂此行為,您可以對 AdminEmailHandler 類別進行子類別化,並覆寫此方法。

篩選器

除了 Python logging 模組提供的篩選器之外,Django 還提供了一些記錄篩選器。

class CallbackFilter(callback)[原始碼]

此篩選器接受回呼函式(應接受單一引數,即要記錄的記錄),並針對通過篩選器的每個記錄呼叫它。如果回呼傳回 False,則不會繼續處理該記錄。

例如,若要從管理員電子郵件中篩除 UnreadablePostError(當使用者取消上傳時引發),您將建立一個篩選函式

from django.http import UnreadablePostError


def skip_unreadable_post(record):
    if record.exc_info:
        exc_type, exc_value = record.exc_info[:2]
        if isinstance(exc_value, UnreadablePostError):
            return False
    return True

然後將其新增至您的記錄組態

LOGGING = {
    # ...
    "filters": {
        "skip_unreadable_posts": {
            "()": "django.utils.log.CallbackFilter",
            "callback": skip_unreadable_post,
        },
    },
    "handlers": {
        "mail_admins": {
            "level": "ERROR",
            "filters": ["skip_unreadable_posts"],
            "class": "django.utils.log.AdminEmailHandler",
        },
    },
    # ...
}
class RequireDebugFalse[原始碼]

僅當 settings.DEBUG 為 False 時,此篩選器才會傳遞記錄。

此篩選器在預設 LOGGING 組態中按如下方式使用,以確保 AdminEmailHandler 僅在 DEBUGFalse 時才向管理員傳送錯誤電子郵件

LOGGING = {
    # ...
    "filters": {
        "require_debug_false": {
            "()": "django.utils.log.RequireDebugFalse",
        },
    },
    "handlers": {
        "mail_admins": {
            "level": "ERROR",
            "filters": ["require_debug_false"],
            "class": "django.utils.log.AdminEmailHandler",
        },
    },
    # ...
}
class RequireDebugTrue[原始碼]

此篩選器與 RequireDebugFalse 相似,不同之處在於僅當 DEBUGTrue 時才會傳遞記錄。

返回頂部