1. ホーム
  2. python

[解決済み] logging.getLogger(__name__)を複数のモジュールで使用する方法

2022-03-04 02:03:44

質問

から logging ハウツー をPython 2.7用に変更しました(強調)。

ロガーに名前を付ける際に使用する良い規約は、モジュールレベルの ロギングを使用する各モジュールで、以下のような名前のロガーがあります。

logger = logging.getLogger(__name__)

これは、ロガー名がパッケージ/モジュールの階層を追跡することを意味します。 また、ロガー名を見れば、どこにイベントが記録されているかが直感的にわかります。

良いアドバイスのようですね。

では、その logging クックブック の代わりにハードコードされたロガー名を使う、複数のモジュールのための例を提供しています。 __name__ 定数を使用します。この例のメイン・モジュールには、次のようなものがあります。

logger = logging.getLogger('spam_application')

そして、quot;auxiliary module"では、次のようになります。

module_logger = logging.getLogger('spam_application.auxiliary')

この例をそのままコピーして、次のような構造のパッケージフォルダに入れました。

cookbook-example
|- __init__.py
|- main_module.py
|- auxiliary_module.py

これは問題なく実行され、主モジュールと補助モジュールの両方から期待通りのログ出力が得られますが、ここで問題が発生します。

ハードコードされたロガー名を __name__ 定数で推奨されているように logging ハウツー のように、Cookbookの例が破綻しています。メインモジュールからロギングメッセージが出るだけで、補助モジュールからは何も出ません。

私は何か明らかなことを見逃しているに違いない。何が間違っているのか、何か思い当たることはありませんか?

注意してください。

よく似た質問と関連する回答がたくさんあります、例. 1 , 2 , 3 , 4 , 5 , 6 などなど。 しかし、そのどれもが、この具体的な問題を扱っていないようです。

--編集部--。

以下は、cookbookの例に基づいた最小限の例で、明示的な名前の文字列を次のように置き換えたものです。 __name__ .

main_module.py

import logging
import auxiliary_module

# create and configure main logger
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# create console handler with a higher log level
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
# create formatter and add it to the handler
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# add the handler to the logger
logger.addHandler(handler)

logger.info('message from main module')
auxiliary_module.some_function()

補助モジュール.py

import logging

# create logger
module_logger = logging.getLogger(__name__) 

def some_function():
    module_logger.info('message from auxiliary module')

解決方法は?

で@shmeeさんが指摘されているように この答え ロガーの階層は、ロガー名の中でドット・ノートを使って明示的に定義する必要があります。つまり、ロガー名が main_module.py は、例えば 'a' の中のロガー名は auxiliary_module.py は、必ず 'a.b' (単なる 'b' の設定を継承させるために、ロガーの 'a' . また、このことは getLogger() ドキュメント .

を使用する場合は、自動的に処理されるはずです。 __name__ で述べたように logging ハウツー :

つまり、ロガー名がパッケージ/モジュールの階層を追跡し、ロガー名を見ただけでどこのイベントが記録されているかが直感的にわかるようになっているのです。

問題は、これを機能させるために __name__ を正しい方法で行う必要がありますが、私はそれをしませんでした。

私の例では、ファイルの構成に問題があります。 cookbook-example パッケージフォルダを使用します。

主モジュールも補助モジュールも同じレベル(つまり同じフォルダ内)にあります。そのため、説明したように ここで は、その __name__ で、メインモジュールの場合は '__main__' (トップレベルのスクリプトであるため)そして __name__ を使用すると、補助モジュールは 'auxiliary_module' (すなわち、ファイル名)ではなく '__main__.auxiliary_module' .

その結果、補助モジュールのロガーは、ルートロガーの子ではなく '__main__' ロガーは、ルートロガーの設定(デフォルトのロギングレベルである WARNING で指定された設定ではなく、"Main Module "で指定された設定になります。

そこで、この例を動作させるために、いくつかのオプションがあります。

  1. 交換 getLogger(__name__) の中に メイン モジュールで getLogger() . これにより、ルートロガーに設定が適用され、したがって 補助モジュールのロガーは @shmee さんの提案の通りです。

  2. 交換 getLogger(__name__) の中に 補助 モジュールで getLogger('__main__.' + __name__) . この結果は、以下のものと同じです。 は元のCookbook-exampleと同じです(ただし、メインのロガーは現在では '__main__' の代わりに 'spam_application' ).