21.Djangoのロギング設定

Djangoアプリケーションでログを出力したりファイルに保存するロギングの設定をしてみましょう。といってもDjangoのロギング設定はほぼPythonの標準ライブラリにあるログファイルハンドラを使っているだけです。

目次

ロギングの設定を追加

ロギングを設定するには次のようにsettings.pyにLOGGINGの項目を追加します。

LOGGING = {
    # スキーマバージョンは1固定
    'version': 1,
    # すでに作成されているロガーを無効化しないための設定 
    'disable_existing_loggers': False,

    # ログの書式設定
    'formatters': {
        # 詳細ログの書式
        'verbose': {
            'format': '{levelname} {asctime} {module} {message}',
            'style': '{',
        },
        # 簡易ログの書式
        'simple': {
            'format': '{levelname} {message}',
            'style': '{',
        },
    },

    # ハンドラ
    'handlers': {
        # コンソール出力用のハンドラ
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'simple',
        },
        # ファイル出力用のハンドラ
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'debug.log'),
            'formatter': 'verbose',
        },
    },

    # ロガー
    'loggers': {
        # djangoフレームワーク用のロガー
        'django': {
            'handlers': ['console', 'file'],
            'level': 'INFO',
            'propagate': True,
        },
        # myappアプリケーション用のロガー
        'myapp': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

ロギングの設定は次の3種類。

1.formatter

formatterにはログメッセージの書式を記述します。

前述の例では詳細ログ用のverboseと簡易ログ用のsimpleを用意しています。

2.handler

handlerはログの出力先と出力するログのレベル、使用するログファイルハンドラ、そして先ほど設定したformatterの中からどれを使用するかを設定します。

前述の例ではコンソール出力用のハンドラとファイル出力用のハンドラの2つを用意しています。

ログのレベルには強い順に「CRITICAL」「ERROR」「WARNING」「INFO」「DEBUG」の5つが用意されています。

「DEBUG」に設定すれば「DEBUG」レベル以上のログが、「INFO」に設定すれば「INFO」レベル以上のログをハンドリングします。

classには使用するログファイルハンドラを指定します。これはPythonの標準ライブラリから次のものなどを選択します。

  • logging.StreamHandler:ログメッセージをストリームに書き込む
  • logging.FileHandler:ログメッセージをファイルに書き込む
  • logging.handlers.RotatingFileHandler:ログファイルのローテーション機能を提供し、ログファイルが特定のサイズに達したときに自動的にローテーションを行う
  • logging.handlers.TimedRotatingFileHandler:時間ベースでログファイルをローテーションすることができ、定期的に新しいログファイルを作成する

また、ファイル出力用のハンドラにはファイルの場所と名前を設定しておきます。

前述の例ではルートディレクトリ直下にdebug.logという名前でログファイルを出力するように設定しています。

3.logger

loggerは実際にログが入力されるオブジェクトです。

先ほど設定したhandlersとログレベルを設定します。

前述の例ではDjangoフレームワーク全体のエラー・警告・開発WEBサーバのアクセスログ用のdjangoロガーと、myappという名前のアプリケーション用のmyappロガーを用意しています。

ロギングを使用するコードを記述

アプリケーション内でログを記録するには次のようにloggingモジュールを使ってロガーを取得・使用します。

例としてわざとエラーを発生させるビューを作成してみましょう。

import logging

logger = logging.getLogger(__name__) # 現在のモジュールのロガーを取得

def sample_view(request):
    try:
        result = 1 / 0  # ZeroDivisionError を発生させるコード
        return HttpResponse("正常な結果")
    except ZeroDivisionError as e:
        logger.error(f"エラーが発生しました: {e}")
        return HttpResponse("エラーが発生しました")

ゼロ除算することでZeroDivisionErrorを発生させるビューです。

続いてこのビューを表示させるルーティングを設定しましょう。

from django.urls import path
from . import views

urlpatterns = [
    path('test/', views.sample_view, name='sample_view'),
]

これで、このページにアクセスするとエラーが発生し、その結果がコンソールに表示され、ログファイルにも記録されます。

動作確認

実際に試してみましょう。

/test/にアクセスすると

画面上の「エラーが発生しました」という文言はただ表示しているだけなので置いておいて

画面上の「エラーが発生しました」という文言はただ表示しているだけなので置いておいて

コンソールに次のようにエラーログが表示されているはずです。

ERROR エラーが発生しました: division by zero
INFO "GET /test/ HTTP/1.1" 200 30

ファイルの方も確認してみましょう。

ログファイル

きちんとエラーログが保存されていますね。

※このサイトのDjango入門編どおり進めてきてWindows環境で試している方は文字コードがCP932になっているはずです。お使いのエディタで文字化けしている場合は文字コードを変更して確認してみてください。

このエントリーをはてなブックマークに追加

コメントを残す

頂いたコメントは一読した後表示させて頂いております。
反映まで数日かかる場合もございますがご了承下さい。