2017-03-09 3 views
1

私はあまりPythonのロギングに慣れていないので、出力をコンソールに出力しようとしています。私はそれが動作するようになっているが、それは出力がコンソールで2回見られ、私は理由がわからないようだ。私は類似の状況についてここで尋ねられた他の質問を見てきましたが、私を助けたものは何も見つかりませんでした。いくつかのモジュール出力をPythonが二度出力する

私は三つのモジュールを持っているが、ミリアンペアメガバイト、MCメインそれらを呼び出すことができます。 mainはこれらの3つのモジュールをインポートし、それらの関数を呼び出します。

ma.py

import logging 
logger = logging.getLogger('test.ma') #test.mb for mb.py/test.mc for mc.py 
logger.setLevel(logging.DEBUG) 

console_log = logging.StreamHandler() 
console_log.setLevel(logging.DEBUG) 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s') 
console_log.setFormatter(formatter) 
logger.addHandler(console_log) 
... 
... 
#right before the end of each module, after I'm finished logging what I need. 
logger.removeHandler(console_log) 

mb.py

import logging 
logger = logging.getLogger('test.mb') 
logger.setLevel(logging.DEBUG) 

console_log = logging.StreamHandler() 
console_log.setLevel(logging.DEBUG) 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s') 
console_log.setFormatter(formatter) 
logger.addHandler(console_log) 
... 
... 
#end of file 
logger.removeHandler(console_log) 

mc.py

import logging 
logger = logging.getLogger('test.mc') 
logger.setLevel(logging.DEBUG) 

console_log = logging.StreamHandler() 
console_log.setLevel(logging.DEBUG) 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s') 
console_log.setFormatter(formatter) 
logger.addHandler(console_log) 
... 
... 
#end of file 
logger.removeHandler(console_log) 

:私はのようにロガーを設定し、各モジュールにおいて

私が持っている主な問題は、出力が2回印刷されていることですプログラムの一部ではフォーマットされていません。どんな助けもありがとう、ありがとう!

答えて

1

グローバルロガーを使用してより良いアプローチはlogging.getLoggerへの呼び出しをラップ機能を使用することです:

import logging 

def get_logger(name): 
    logger = logging.getLogger(name) 
    if not logger.handlers: 
     # Prevent logging from propagating to the root logger 
     logger.propagate = 0 
     console = logging.StreamHandler() 
     logger.addHandler(console) 
     formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s') 
     console.setFormatter(formatter) 
    return logger 

def main(): 
    logger = get_logger(__name__) 
    logger.setLevel(logging.DEBUG) 
    logger.info("This is an info message") 
    logger.error("This is an error message") 
    logger.debug("This is a debug message") 

if __name__ == '__main__': 
    main() 

出力

2017-03-09 12:02:41,083 - __main__ - This is an info message 
2017-03-09 12:02:41,083 - __main__ - This is an error message 
2017-03-09 12:02:41,083 - __main__ - This is a debug message 

注:関数を使用すると、logger.propagateFalseに設定して、ログメッセージがルートロガーに送られないようにすることもできます。これはほぼ確実にあなたが見ている出力の重複の原因です。

更新: を呼び出した後、logger.setLevelを呼び出すことによって、希望のレベルを設定する必要があります。これが行われないと、エラーメッセージだけが表示されます。

+0

私はヘルパー3つすべてのモジュールがロギングを必要とする機能を呼び出します。だから、私はそのモジュールにこの関数を追加しました(上記のformatter/setLevelの変更を加えました)。それぞれのモジュールで、 'logger = helper.get_logger( 'test')'を呼び出すだけです。今私がプログラムを実行すると、ログは全く表示されず、印刷文だけが表示されます – bbakp3

+0

レベルを 'logging.DEBUG'に設定するには' logger.setLevel'を呼び出さなければなりません。それ以外の場合は、エラーメッセージのみが表示されます。完全な例になるようにコードを更新しました。 –

+0

ヘルパーモジュールのメソッドに 'logger.setLevel'関数を追加しました。 – bbakp3

0

複数のモジュールを1つのグローバルファイルにログインするには、ロギングインスタンスを作成し、そのインスタンスを好きなモジュールで取得します。だから、メインでは、たとえば、私が持っているでしょう:

import logging 

logging.basicConfig(filename='logfile.log', level=logging.DEBUG) 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s') 
logger = logging.getLogger('Global Log') 

その後、私はこのログに追加できるようにしたいすべてのモジュールでは、私が持っている:

import logging 
logger = logging.getLogger('Global Log') 

を今毎回、あなたはロガーにアクセスあなたのモジュールで、あなたは同じロギングインスタンスにアクセスしています。この方法では、ロガーを一度設定してフォーマットするだけで済みます。

ドキュメント内のインスタンスをロギングについての詳細: https://docs.python.org/2/library/logging.html#logging.getLogger

+0

私は試してみましたが動作していたようですが、私がよく見てから、まだ2回出力されている部分があります。最初は時間/名前/メッセージの一般的な書式ですが、2回目は出力となります。 DEBUG:メッセージ – bbakp3

+0

ドキュメントによれば(私のリンク先の短いところ)モジュールレベルの関数を使用すると、ハンドラーがロガーに複数回追加されることがあります。これはPython 2.7-3.2の問題です。私は解決策がここにあるのか分かりません。私は3.4.2で作業していますが、この問題はありませんでした(私はそれがあまり役に立たないことを知っています!) –

+0

あなたの助けをありがとう:) – bbakp3

関連する問題