【Django】ログファイルを出力する方法

sanagi
2024-07-18
2024-07-18

こんにちは、sanagiです。

DjangoのWebアプリを公開する際にログファイルを蓄積させたりするかと思います。

今回はコンソールとファイル両方に、ログ出力する方法について紹介したいと思います。

はじめに

  • Pythonのバージョン:     3.11
  • Djangoのバージョン:     4.2.4

まず、Djangoアプリの構成は以下の通りです。
「以下の'logs'フォルダ(空フォルダ)にログファイルを作成 + コンソールにログ出力する」ように設定していきます。

django_pj/
├── django_app
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   ├── __init__.py
│   ├── models.py
│   ├── urls.py
│   └── views.py
├── logs
├── manage.py
├── django_pj
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── static
│   ├── css
│   └── js
└── templates
      └── index.html

settings.pyを編集する

django_pj/django_pj/settings.pyを編集し、ログファイルとコンソール両方に出力するように設定します。

import os
import datetime

today = datetime.date.today().strftime('%Y%m%d')
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'development': {
            'format': '%(asctime)s [%(levelname)s] %(message)s'
        },
    },
    'handlers': {
        'console': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'development',
        },
        'file': {
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, f'logs/log_{today}.log'),
            'formatter': 'development',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file', 'console'],
            'level': 'INFO',
            'propagate': True,
        }
    },
}

設定内容は、大きく3つのセクションに分かれます。以下に説明していきます。

■formatters

ここではログのフォーマットを決定します。フォーマットのこの部分は、

'format': '%(asctime)s [%(levelname)s] %(message)s'

このような意味になります。

  • asctime:ログの発生日時
  • levelname:ログレベル
  • message:ログメッセージ内容

■handlers

ここでは、「どのフォーマッターを使用するか、何に出力するか、ファイルの出力先」を設定しています。

'console'セクションではログをコンソール上に出力する設定、'file'セクションではログをファイルとして出力する設定を行っています。

'file'セクションの下記部分では、1日毎にファイルが分かれるようにファイル名を設定しています。また、ファイルの保存先パスも指定しています。

'filename': os.path.join(BASE_DIR, f'logs/log_{today}.log')

BASE_DIRはdjangoのプロジェクトを作成したときに、デフォルトで以下のようなコードが入っていると思いますのでそのまま使えます。

    BASE_DIR = Path(__file__).resolve().parent.parent

■loggers

ここでは、どのhandlerを使うか設定しています。また、どのログレベルから記録するか指定しています。

ログレベルは以下のような種類があります。

  1. DEBUG:詳細な情報やデバッグ目的の情報を記録するためのレベル。通常は開発時に使用されます。
  2. INFO:一般的な情報を記録するためのレベル。通常は開発や本番環境で使用されます。
  3. WARNING:潜在的な問題や警告を示すためのレベル。プログラムが予期しない状況に遭遇した場合に使用されます。
  4. ERROR:重要なエラーが発生したことを示すためのレベル。プログラムの実行に影響を与えるエラーが発生した場合に使用されます。
  5. CRITICAL:致命的なエラーが発生したことを示すためのレベル。プログラムが停止したり、重大な問題が発生した場合に使用されます。

ここでは'INFO'を設定しているので'INFO'以上のログレベル(INFO, WARNING, ERROR, CRITICAL)が記録されることになります。

お気づきの方もいると思いますが、handlersにもログレベルを設定しています。
両方設定することで、handlersで設定したログレベルをさらにloggersで絞ることができます。

loggerを呼び出してログを記録する

ログを記録するために、アプリ側でロガーを呼び出す必要があります。

例えば、django_pj/django_app/views.py内に以下のように書いてログを記録するように設定します。

import logging


logger = logging.getLogger('django')

def index(request):
        logger.info('indexを呼び出し')

        return HttpResponse(status=200)

そしたら、こんな感じでコンソール上にログが出力されると思います。

2024-05-28 16:28:17,001 [INFO] indexを呼び出した
2024-05-28 16:28:19,752 [INFO] "GET /django_app/ HTTP/1.1" 200 545546

django_pj/logsフォルダも見て頂くと、「log_yyyymmdd(今日の日付).log」というファイルが生成されており、同様のログが記録されていると思います。

おわり

いかがでしたか?

そこまで難しい手順ではないので、ぜひやってみてください!