Python
Django

[Django] プロジェクト構成のベストプラクティスを探る - 4.ログ設定をシンプルにする

この記事について

Djangoで本番運用やチーム開発を行うに当たって、プロジェクトの初期構成にどのように手を入れたらよいかを、The Twelve Factorsなどを参考にまとめたメモです。

Djangoのログファイル設定は面倒なのか?

Djangoのログ出力はPython標準の「logging」というモジュールを利用しています。

しかしこのloggingが多機能すぎるためか、設定方法を調べてもやたらと細かい内容のものが多く、結局どうしたら基本的な設定ができるのかわからないケースが多いです。

というわけで、とりあえずこれだけやればOKという設定を残しておきます。

参考

今回はこちらの本を参考(というかほぼ写し…)にさせていただきました。

現場で使える 基礎 Django(技術書典4バージョン)
https://booth.pm/ja/items/823251

内容が非常に充実していて助かります。

ログ出力の要件

開発環境

出力先:標準出力(コンソール)
出力内容:

  • 自分で書いたログ出力
  • エラー・警告メッセージ
  • 開発WEBサーバへのリクエスト
  • 実行SQL

本番環境

出力先:ファイル

  • 自分で書いたログ出力
  • エラー・警告メッセージ

設定内容

開発と本番の設定ファイルを分離済みであるという前提とします。

開発環境

config/settings/local.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'local': {
            'format': '%(asctime)s [%(levelname)s] %(pathname)s:%(lineno)d %(message)s'
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'local',
        },
    },
    'loggers': {
        # 自作したログ出力
        '': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,
        },
        # Djangoのエラー・警告・開発WEBサーバのアクセスログ
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
            'propagate': False,
        },
        # 実行SQL
        'django.db.backends': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False,
        },
    }
}

本番環境

project/settings/production.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'production': {
            'format': '%(asctime)s [%(levelname)s] %(process)d %(thread)d '
                      '%(pathname)s:%(lineno)d %(message)s'
        },
    },
    'handlers': {
        'file': {
            'class': 'logging.FileHandler',
            'filename': 'logs/django.log',  #環境に合わせて変更
            'formatter': 'production',
            'level': 'INFO',
        },
    },
    'loggers': {
        # 自作したログ出力
        '': {
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': False,
        },
        # Djangoの警告・エラー
        'django': {
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': False,
        },
    },
}

ローテーション設定

ログローテーションの行う場合はhandlersの設定を変更します。

ファイルサイズによるローテーション

    'handlers': {
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django.log',
            'formatter': 'production',
            'maxBytes': 1024 * 1024 * 100,  # サイズ(100MB)
            'backupCount': 7, # 世代数
        },
    },

期間によるローテーション

    'handlers': {
        'file': {
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': 'logs/django.log',
            'formatter': 'production',
            'when': 'D', # 単位は日
            'interval': 1, # 一日おき
            'backupCount': 7, # 世代数
        },
    },

※期間指定のフォーマットについてはpython公式を参照

注意:Windowsでローテションは使えない

Windows環境ではファイルロック処理の違いでRotatingFileHandlerが正常に動きません。ローテーションは別の方法で行ってください(WEBサーバ停止時にリネーム等)。

参考:[Python]Windows上でspawnとログローテートの相性が悪い件

ログ監視方法

エラーや警告の監視は、ログファイル監視エージェントを使って通知するようにします。

loggingから直接通知することもできますが、構成が複雑になるのでやめた方がいいとされています。

参考:The Twelve Factor XI. ログ