2011-07-18 10 views
36

私はPythonログを使用しています。何らかの理由で、すべてのメッセージが2度表示されています。Pythonログでログメッセージが2回表示される

私はロギングを構成するモジュールを持っている:

if __name__ == '__main__': 
    tom = Boy() 
    tom.configure_logging(LOG_FILENAME) 
    tom.buy_ham() 

そしてbuy_hamモジュール、たとえば内、私は呼びたい:

# BUG: It's outputting logging messages twice - not sure why - it's not the propagate setting. 
def configure_logging(self, logging_file): 
    self.logger = logging.getLogger("my_logger") 
    self.logger.setLevel(logging.DEBUG) 
    self.logger.propagate = 0 
    # Format for our loglines 
    formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") 
    # Setup console logging 
    ch = logging.StreamHandler() 
    ch.setLevel(logging.DEBUG) 
    ch.setFormatter(formatter) 
    self.logger.addHandler(ch) 
    # Setup file logging as well 
    fh = logging.FileHandler(LOG_FILENAME) 
    fh.setLevel(logging.DEBUG) 
    fh.setFormatter(formatter) 
    self.logger.addHandler(fh) 

その後、私はロギングを設定するには、このメソッドを呼び出します:

self.logger.info('Successfully able to write to %s' % path) 

そして、何らかの理由で、すべてのメッセージが2回表示されます。ストリームハンドラの1つをコメントしましたが、それと同じことです。奇妙なもののビット、なぜこれが起こっているのかわからない...笑。私は明らかな何かを逃したと仮定します。

乾杯、 ビクター

+0

'configure_logging()'がコンストラクタから2回呼び出されていませんか? Boy()のインスタンスは1つしか作成されていませんか? –

答えて

60

あなたが二回(多分Boy__init__方法で)configure_loggingを呼び出している:getLoggerが同じオブジェクトを返しますが、同様のハンドラがすでにロガーに追加されている場合addHandlerチェックしません。

そのメソッドへの呼び出しをトレースし、これらのメソッドを削除してみてください。またはBoy__init__方法でFalseに初期化フラグlogging_initializedを設定し、logging_initializedTrueであれば何もしないように、そしてあなたがロガーを初期化した後Trueに設定するconfigure_loggingを変更します。

あなたのプログラムが複数のBoyのインスタンスを作成した場合、あなたはハンドラを追加グローバルconfigure_logging機能で物事を行う方法、およびだけself.logger属性を初期化Boy.configure_logging方法を変更する必要があります。

これを解決する別の方法は、ハンドラがあなたのロガーの属性を確認することである:

logger = logging.getLogger('my_logger') 
if not logger.handlers: 
    # create the handlers and call logger.addHandler(logging_handler) 
+1

はい、あなたは正直に馬鹿です。私はそれを__init__と明示的に他の場所でも呼びました。笑。ありがとう=)。 – victorhooi

+0

ありがとうございます。あなたのソリューションは今日私を助けました。 – Tammy

+1

私の場合、彼らは6回出現していました。私は6 oopクラスで同じタイプのロガーを宣言しているので疑いがありました – answerSeeker

5

ハンドラを使用して、外部から呼び出すたびに追加されます。あなたの仕事を終えた後、ハンドラをRemoveing試してみてください。

self.logger.removeHandler(ch) 
+0

私はpython 2.7で 'logger.handlers.pop()'を使いましたが、 – radtek

2

私はPythonの初心者だけど、これは(Pythonの2.7)私のために働くように見えた

while logger.handlers: 
    logger.handlers.pop() 
1

あなたがこの問題を見て、あなたのしている場合「再docsからabarnertの答えhere

を参照してください2回ハンドラを追加していない:

注:ハンドラーをロガーと先祖の の1つ以上にアタッチする場合、同じレコードを複数回送信することがあります。一般に、 は、複数のロガーにハンドラを接続する必要はありません。 を ロガー階層の中で最も高い適切なロガーにアタッチするだけで、すべての子孫がすべてのログを記録します。 ロガー、それらの伝搬設定がTrueのままになっている場合に限ります。A 一般的なシナリオは、ハンドラーをルート・ロガーにのみ接続し、 に伝播させて残りを処理することです。

あなたは、「テスト」のカスタムハンドラをしたい、とあなたはそのメッセージもルートハンドラに行くしたくないのであれば、答えは簡単です:その伝播フラグをオフにします。

ロガー.propagate = False

関連する問題