デバッグ情報とドキュメントを印刷する代わりに、ログ モジュールを使用したいと思います。目標は、DEBUG レベルでコンソールに印刷し、INFO レベルでファイルにログを記録することです。
私はロギング モジュールに関する多くのドキュメント、クックブック、その他のチュートリアルを読みましたが、それをどのように使用すれば希望どおりに使用できるのかわかりませんでした。(私は python25 を使用しています)
ログが書き込まれるモジュールの名前をログファイルに表示したいです。
ドキュメントには、使用する必要があると書かれていますlogger = logging.getLogger(__name__)
が、他のモジュール/パッケージのクラスで使用されるロガーを宣言して、メイン ロガーと同じハンドラーを使用するにはどうすればよいでしょうか? '親' を認識するには、使用できますlogger = logging.getLogger(parent.child)
が、誰がクラス/メソッドを呼び出したかはどこでわかりますか?`
以下の例は私の問題を示しています。これを実行すると、出力にはログのみが含まれ__main__
、ログは無視されます。Class
これは私のメインファイル:
# main.py
import logging
from module import Class
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# create file handler which logs info messages
fh = logging.FileHandler('foo.log', 'w', 'utf-8')
fh.setLevel(logging.INFO)
# create console handler with a debug log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# creating a formatter
formatter = logging.Formatter('- %(name)s - %(levelname)-8s: %(message)s')
# setting handler format
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(fh)
logger.addHandler(ch)
if __name__ == '__main__':
logger.info('Script starts')
logger.info('calling class Class')
c = Class()
logger.info('calling c.do_something()')
c.do_something()
logger.info('calling c.try_something()')
c.try_something()
モジュール:
# module.py
imnport logging
class Class:
def __init__(self):
self.logger = logging.getLogger(__name__) # What do I have to enter here?
self.logger.info('creating an instance of Class')
self.dict = {'a':'A'}
def do_something(self):
self.logger.debug('doing something')
a = 1 + 1
self.logger.debug('done doing something')
def try_something(self):
try:
logging.debug(self.dict['b'])
except KeyError, e:
logging.exception(e)
出力コンソール:
- __main__ - INFO : Script starts
- __main__ - INFO : calling class Class
- __main__ - INFO : calling c.do_something()
- __main__ - INFO : calling c.try_something()
No handlers could be found for logger "module"
また、上記のように各クラスで新しいロガーを宣言せずに、ログファイルでログが発生したモジュール名を取得する方法はありますか? また、この方法では、何かをログに記録するたびに実行する必要があります。コード全体でまたは をself.logger.info()
使用することを好みます。logging.info()
logger.info()
グローバル ロガーはおそらくこれに対する正しい答えでしょうか? しかし、そうすると、ログにエラーが発生したモジュールが取得されなくなります...
最後の質問です。これは Python 的なものですか? それとも、このようなことを正しく行うためのより良い推奨事項はありますか。
ベストアンサー1
'__main__'
メイン モジュールでは、 name (または、このケースでは に相当するもの)のロガーを設定しています__name__
が、module.py では別のロガーを使用しています。モジュールごとにロガーを設定するか、メイン モジュールでルート ロガーを設定 ( を設定logging.getLogger()
) して、プロジェクト内のすべてのロガーにデフォルトで適用する必要があります。
ロガーの設定には設定ファイルを使用することをお勧めします。次のリンクから、ベストプラクティスについてよく理解できるはずです。http://victorlin.me/posts/2012/08/26/good-logging-practice-in-python
編集: フォーマッタで %(module) を使用して、ログ メッセージにモジュール名を含めます。