如何設定和使用日誌記錄

Django 提供一個可輕鬆擴充的預設日誌記錄組態

進行基本的日誌記錄呼叫

若要從您的程式碼內傳送日誌訊息,請將日誌記錄呼叫放入其中。

不要試圖在 settings.py 中使用日誌記錄呼叫。

Django 日誌記錄設定方式是 setup() 函式的一部分,這表示放置在 settings.py 中的日誌記錄呼叫可能無法如預期運作,因為*日誌記錄在該點不會設定*。若要探索日誌記錄,請使用如下例所示的視圖函式。

首先,匯入 Python 日誌記錄程式庫,然後使用 logging.getLogger() 取得記錄器實例。向 getLogger() 方法提供一個名稱,以識別它以及它發出的記錄。一個不錯的選項是使用 __name__ (有關更多資訊,請參閱下方的 使用記錄器命名空間),它會將目前的 Python 模組的名稱作為點分隔的路徑提供。

import logging

logger = logging.getLogger(__name__)

在模組層級執行此宣告是一個很好的慣例。

然後在函式中,例如在視圖中,將記錄傳送到記錄器

def some_view(request):
    ...
    if some_risky_state:
        logger.warning("Platform is running at risk")

當執行此程式碼時,包含該訊息的 LogRecord 將會傳送到記錄器。如果您正在使用 Django 的預設日誌記錄設定,則訊息會出現在主控台中。

以上範例中使用的 WARNING 層級是幾個日誌記錄嚴重性層級之一:DEBUGINFOWARNINGERRORCRITICAL。因此,另一個範例可能是

logger.critical("Payment system is not responding")

重要

預設情況下,層級低於 WARNING 的記錄不會出現在主控台中。變更此行為需要額外的設定。

自訂日誌記錄設定

雖然 Django 的日誌記錄設定可立即運作,但您可以透過一些額外的設定來精確控制日誌傳送到各種目的地的方式 – 傳送到日誌檔案、外部服務、電子郵件等等。

您可以設定

  • 記錄器對應,以決定哪些記錄傳送到哪些處理常式

  • 處理常式,以決定它們如何處理接收到的記錄

  • 篩選器,以提供額外的記錄傳輸控制,甚至可以就地修改記錄

  • 格式器,將 LogRecord 物件轉換為字串或其他形式,供人類或其他系統使用

有各種方式可以設定日誌記錄。在 Django 中,最常用的是 LOGGING 設定。該設定使用 dictConfig 格式,並擴充預設日誌記錄設定

如需說明如何將您的自訂設定與 Django 的預設設定合併,請參閱 設定日誌記錄

如需其他設定日誌記錄方式的詳細資訊,請參閱 Python 日誌記錄 文件。為了簡單起見,本文件僅考慮透過 LOGGING 設定進行設定。

基本日誌記錄設定

設定日誌記錄時,應

建立 LOGGING 字典

在您的 settings.py

LOGGING = {
    "version": 1,  # the dictConfig format version
    "disable_existing_loggers": False,  # retain the default loggers
}

disable_existing_loggers 設定為 False,保留並擴充預設日誌記錄設定幾乎總是有意義的。

設定處理常式

此範例設定了一個名為 file 的單一處理常式,該處理常式使用 Python 的 FileHandler 將層級為 DEBUG 或更高的日誌儲存到檔案 general.log(位於專案根目錄)

LOGGING = {
    # ...
    "handlers": {
        "file": {
            "class": "logging.FileHandler",
            "filename": "general.log",
        },
    },
}

不同的處理常式類別採用不同的設定選項。如需有關可用處理常式類別的詳細資訊,請參閱 Django 提供的 AdminEmailHandler,以及 Python 提供的各種 處理常式 類別

也可以在處理常式上設定日誌記錄層級(預設情況下,它們接受所有層級的日誌訊息)。使用上述範例,新增

{
    "class": "logging.FileHandler",
    "filename": "general.log",
    "level": "DEBUG",
}

會定義一個僅接受層級為 DEBUG 或更高的記錄的處理常式設定。

設定記錄器對應

若要將記錄傳送到此處理常式,請設定記錄器對應來使用它,例如

LOGGING = {
    # ...
    "loggers": {
        "": {
            "level": "DEBUG",
            "handlers": ["file"],
        },
    },
}

對應的名稱決定了它將處理哪些日誌記錄。此設定 ('') 是*未命名*的。這表示它會處理來自*所有*記錄器的記錄(請參閱下方的 使用記錄器命名空間,瞭解如何使用對應名稱來決定它將處理記錄的記錄器)。

它會將層級為 DEBUG 或更高的訊息轉送到名為 file 的處理常式。

請注意,記錄器可以將訊息轉送到多個處理常式,因此記錄器和處理常式之間的關係是多對多的。

如果您執行

logger.debug("Attempting to connect to API")

在您的程式碼中,您會在專案根目錄中的檔案 general.log 中找到該訊息。

設定格式器

預設情況下,最終的日誌輸出包含每個 日誌 記錄的訊息部分。如果您想要包含額外的資料,請使用格式器。首先命名並定義您的格式器 – 此範例定義了名為 verbosesimple 的格式器

LOGGING = {
    # ...
    "formatters": {
        "verbose": {
            "format": "{name} {levelname} {asctime} {module} {process:d} {thread:d} {message}",
            "style": "{",
        },
        "simple": {
            "format": "{levelname} {message}",
            "style": "{",
        },
    },
}

style 關鍵字可讓您為 str.format() 指定 {,或為 string.Template 格式指定 $;預設值為 $

如需您可以包含的 LogRecord 屬性,請參閱 LogRecord 屬性

若要將格式器套用到處理常式,請將 formatter 項目新增至處理常式的字典,並依名稱參照該格式器,例如

"handlers": {
    "file": {
        "class": "logging.FileHandler",
        "filename": "general.log",
        "formatter": "verbose",
    },
}

使用記錄器命名空間

未命名的日誌配置 '' 會捕獲任何 Python 應用程式的日誌。具名的日誌配置只會捕獲來自名稱匹配的日誌記錄器的日誌。

日誌記錄器實例的命名空間是使用 getLogger() 定義的。例如在 my_appviews.py

logger = logging.getLogger(__name__)

會在 my_app.views 命名空間中建立一個日誌記錄器。__name__ 可讓您根據專案應用程式中的來源自動組織日誌訊息。它還可以確保您不會遇到名稱衝突。

名稱為 my_app.views 的日誌記錄器映射將捕獲來自此日誌記錄器的記錄

LOGGING = {
    # ...
    "loggers": {
        "my_app.views": {...},
    },
}

名稱為 my_app 的日誌記錄器映射將更具允許性,捕獲來自 my_app 命名空間中任何位置的日誌記錄器的記錄(包括 my_app.viewsmy_app.utils 等等)

LOGGING = {
    # ...
    "loggers": {
        "my_app": {...},
    },
}

您也可以明確定義日誌記錄器命名空間

logger = logging.getLogger("project.payment")

並相應地設定日誌記錄器映射。

使用日誌記錄器階層和傳播

日誌記錄器命名是階層式的。my_appmy_app.views 的父級,而 my_app.views 又是 my_app.views.private 的父級。除非另有指定,否則日誌記錄器映射會將它們處理的記錄傳播到它們的父級 - 來自 my_app.views.private 命名空間中的日誌記錄器的記錄將由 my_appmy_app.views 的映射處理。

要管理此行為,請在您定義的映射上設定傳播鍵

LOGGING = {
    # ...
    "loggers": {
        "my_app": {
            # ...
        },
        "my_app.views": {
            # ...
        },
        "my_app.views.private": {
            # ...
            "propagate": False,
        },
    },
}

propagate 預設為 True。在此範例中,來自 my_app.views.private 的日誌將不會由父級處理,但來自 my_app.views 的日誌將會處理。

設定響應式日誌記錄

當日誌包含盡可能多的資訊時,它最有用,但並非包含您不需要的資訊 - 而您需要的資訊量取決於您正在做的事情。當您正在除錯時,您需要的資訊級別如果在生產環境中處理會過多且無益。

您可以設定日誌記錄,以便在您需要時提供您需要的詳細程度。與手動變更設定來實現此目的相比,更好的方法是根據環境自動套用設定。

例如,您可以在您的開發和測試環境中適當地設定環境變數 DJANGO_LOG_LEVEL,並在日誌記錄器映射中使用它,如下所示

"level": os.getenv("DJANGO_LOG_LEVEL", "WARNING")

- 因此,除非環境指定了較低的日誌等級,否則此設定只會將嚴重程度為 WARNING 或更高的記錄轉發到其處理程序。

設定中的其他選項(例如處理程序的 levelformatter 選項)也可以類似地管理。

返回頂部