Djangoセットアップのデフォルトのロギング


94

Djangoインストール用の「デフォルト」ロガーを設定する方法がわかりません。でDjango 1.3の新しいLOGGING設定を使用したいと思いsettings.pyます。

私はDjango Logging Docの例を見てきましたが、特定のロガーのロギングを行うハンドラーのみをセットアップしているように見えます。彼らの例の場合、「django」、「django.request」、および「myproject.custom」という名前のロガーのハンドラーをセットアップします。

私がしたいのは、デフォルトlogging.handlers.RotatingFileHandlerですべてのロガーを処理するデフォルトを設定することだけです。つまり、プロジェクトのどこかに新しいモジュールを作成し、それが次のように示されている場合my_app_name.my_new_module、これを実行して、すべてのロギングをローテーションファイルログに移動できるはずです。

# In file './my_app_name/my_new_module.py'
import logging
logger = logging.getLogger('my_app_name.my_new_module')
logger.debug('Hello logs!') # <-- This should get logged to my RotatingFileHandler that I setup in `settings.py`!

回答:


153

理解した...

空の文字列で参照することにより、「catch all」ロガーを設定します''

例として、次のセットアップでは、に保存されるログイベントをlogs/mylog.log除いて、すべてのログイベントがに保存さdjango.requestれていlogs/django_request.logます。ので'propagate'に設定されているFalse私のためにdjango.requestロガー、ログイベントは、「すべてをキャッチ」ロガーに到達することはありません。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/mylog.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },  
        'request_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django_request.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
    },
    'loggers': {
        '': {
            'handlers': ['default'],
            'level': 'DEBUG',
            'propagate': True
        },
        'django.request': {
            'handlers': ['request_handler'],
            'level': 'DEBUG',
            'propagate': False
        },
    }
}

2
クリス、これに関するDjangoのドキュメントは混乱していません。これをありがとう。

5
小さな修正:このコメントは、SQLロギングがdjango.requestロガーの影響を受けることを示唆しています。SQLロギングをリダイレクトするには、「django.db」のロガーを定義します。django.requestロガーは5xxおよび4xx http応答を処理します。
rych

これは私のような他の初心者を助けます:ロガーはログファイルを作成しlogs/ますが、最初にフォルダを作成する必要があります:-)。そうしないと、を実行し./manange.py runserverたときにエラーが発生します。@Chris W.ロギング設定の例をありがとう。それは私を大いに助けてくれました!
hobbes3

3
@arindamroychowdhury上記の設定を行うlogger = logging.getLogger('foo'); logger.warn('bar');と、defaultハンドラーがそのロギングをキャッチし、次のようなもの<time> WARN: foo: barが終了しますlogs/mylog.log
Chris W.

8
ありがとうございますこれはルートロガーを意味するようです。この有用な情報はDjangoのドキュメントにはありませんでした。
EinoMäkitalo

25

回答で述べたように、デフォルトのロガーを定義する1つのオプションは、空の文字列をキーとして使用することです。

ただし、意図された方法はroot、ロギング構成辞書のキーの下に特別なロガーを定義することだと思います。私はこれをPythonのドキュメントで見つけました:

root-これはルートロガーの設定になります。構成の処理は、設定がpropagate適用されないことを除いて、すべてのロガーの場合と同じです。

以下は、rootキーを使用するように変更した回答の構成です。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/mylog.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },  
        'request_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django_request.log',
            'maxBytes': 1024*1024*5, # 5 MB
            'backupCount': 5,
            'formatter':'standard',
        },
    },
    'root': {
        'handlers': ['default'],
        'level': 'DEBUG'
    },
    'loggers': {
        'django.request': {
            'handlers': ['request_handler'],
            'level': 'DEBUG',
            'propagate': False
        },
    }
}

公平を期すために、2つの構成の動作に違いは見られません。空の文字列キーでロガーを定義すると、ルートロガーlogging.getLogger('')が返されるため、ルートロガーが変更されるようです。

私が好む唯一の理由'root'オーバーは''、それがルートロガーの変更について明示的であるということです。興味'root'がある''場合は、ルートエントリが最後に処理されるため、両方を定義するとオーバーライドされます。


うん、そうだ、誤解してすみません!'root'の代わりに ''を使用するのはやや論理的ですが、root2.6 fileConfigロジックから2.7 dictConfig 1にスムーズに移行するプロセスで、エントリをdictのルートに移動するのは少し矛盾しています。
アントニーハッチキンス2014

2
import logging
logger = logging.getLogger(__name__)

追加後:

logging.basicConfig(
    level = logging.DEBUG,
    format = '%(name)s %(levelname)s %(message)s',
)

形式を次のように変更できます。

format = '"%(levelname)s:%(name)s:%(message)s"  ',

または

format = '%(name)s %(asctime)s %(levelname)s %(message)s',

0

rootキーと空の''ロガーの両方がconfig dictで参照されている場合に使用される構成を確認する簡単なサンプルを作成しました。

import logging.config

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'fmt1': {
            'format': '[FMT1] %(asctime)-15s %(message)s',
        },
        'fmt2': {
            'format': '[FMT2] %(asctime)-15s %(message)s',
        }
    },
    'handlers': {
        'console1': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'fmt1',
        },
        'console2': {
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'fmt2',
        },
    },
    # First config for root logger: console1 -> fmt1
    'root': {
        'handlers': ['console1'],
        'level': 'DEBUG',
        'propagate': True,
    },
    'loggers': {
        # Second config for root logger: console2 -> fmt2
        '': {
            'handlers': ['console2'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

logging.config.dictConfig(LOGGING)

l1 = logging.getLogger()
l2 = logging.getLogger('')
root = logging.root

l1.info("l1")
l2.info("l2")
root.info("root logger")

次の結果を出力します。

[FMT1] 2018-12-18 17:24:47,691 l1
[FMT1] 2018-12-18 17:24:47,691 l2
[FMT1] 2018-12-18 17:24:47,691 root logger

rootキーの下の構成が最も優先度が高いことを示します。ブロックが削除されると、結果は次のようになります。

[FMT2] 2018-12-18 17:25:43,757 l1
[FMT2] 2018-12-18 17:25:43,757 l2
[FMT2] 2018-12-18 17:25:43,757 root logger

両方の場合において、Iは、デバッグおよびすべての3つのロガー(と判断することができたl1l2とはroot)同じロガーインスタンス、ルートロガーを参照します。

私のように、ルートロガーを構成する2つの異なる方法で混乱した他の人を助けることを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.