2016-07-08 6 views
0

今、私は、それぞれ独自のインスタンスデータを持つ複数のスレッドを生成するプロセスを持っています。私は、コンテキスト固有の情報を、派生スレッドクラスの内部のさまざまなメソッドを通して呼び出されるロギングステートメントに挿入する必要があります(この場合、コンテキスト固有の情報は、スレッドを起動させた人の電子メールです) 。ここでロガーでチェックされている最初のフィルタのみ

私は現在、この場合は

class InjectionFilter(logging.Filter):                
    def __init__(self, runner):                  
    self.runner = runner                  

    def filter(self, record):                  
    record.email = self.runner.authorEmail           
    return (record.threadName == self.runner.getName()) 

「ランナー」を使用していますフィルタは、のgetName()を呼び出すために、したがって能力、スレッドのサブクラスであるクラスです。

フィルタの場合、ランナークラスの__init__メソッドのログインスタンスにフィルタの新しいインスタンスを追加することによって、新しいスレッドが作成されるたびに新しいフィルタをインスタンス化します。

class ThreadRunner(Thread): 
    def __init__(self, other_info): 
    ... other things set here ... 
    ifilter = InjectionFilter(self) 
    _log.addFilter(ifilter) 

ここで、_logは、これらすべてのスレッドのグローバルロギングインスタンスです。 そしてフィルターは完璧に追加されます!
私は_log.filtersと電話して、それぞれのフィルタを見ることができます。 これは全く問題なく動作しています。

動作しないのは、ロギングステートメントを読むときに最初のフィルタのみが実際にチェックされていることです。

デバッグ文をフィルタに追加して、内部で何が起きているかを確認しました。私はマネージャーを起動して、複数のスレッドを起動するとeprintsys.stderr

def filter(self, record):                  
    record.email = self.runner.authorEmail           
    eprint("Record threadname is %s" % record.threadName)          
    eprint("Runner threadname is %s" % self.runner.getName())         
    eprint("Runner equals Record: %s" % (record.threadName == self.runner.getName())) 
    return (record.threadName == self.runner.getName()) 

に印刷するだけのヘルパーメソッドですが、私は同じフィルタチェック毎回、作成された常に最初のフィルタを取得します。

サンプルログ出力

Record threadname is Thread-52 
Runner threadname is Thread-52 
Runner equals Record: True 
... 
Record threadname is Thread-53 
Runner threadname is Thread-52 
Runner equals Record: False 
... 
Record threadname is Thread-54 
Runner threadname is Thread-52 
Runner equals Record: False 

は、それは今までスレッド-52をするために、作成された最初のフィルタであることを比較します。私は

ロガーにすべてのフィルタが適用さ
for fil in _log.filters: 
    print(fil.runner.getName()) 

をプリントアウトしている場合しかし、私はだから私はすべてのフィルタはロガーに適用されていることを知っているが、それらはすべてではありません

Thread-52 
Thread-53 
Thread-54 

を取得します何らかの理由で比較されている。私はFalse最初のスレッドの後にすべての単一のログステートメントのフィルター比較ステートメントを取得します。

Pythonは最初のフィルタのみをチェックしますか?私は間違って何かを設定していますか?私はここに何かを逃していますか

私はこれがかなり簡単なはずだと思うが、Pythonのログ記録のドキュメントは私にとって最も理にかなっていない。

もっと文脈が必要な場合、または私が不明な場合は、私にお知らせください。私はこれをやりたい母

答えて

0

は、Pythonでログインするための(笑、あなたは私より優れたプログラマだからか、多分あなたは文句を言わない)誰もが今までに、将来的にこのような何かに引っかかる場合には、

をそれを考え出しましたログメッセージ全体を削除するためにフィルタの1つが失敗する必要があります。フィルタをチェックして、少なくとも1つが通過したかどうかを確認すると思っていましたが、その思考プロセスが今どのように壊れているのかが分かります。

この問題を回避するため、私はスポーンされたスレッドごとに新しいハンドラをインスタンス化し、フィルタの新しいインスタンスをそのハンドラに適用してから、ハンドラを_logインスタンスに適用しました。

ここで_logには多くのハンドラがあり、ハンドラのそれぞれには1つのフィルタがあります。ロギングステートメントは各ハンドラをチェックし、適切なフィルタを持つものだけが送信されます。 :)

関連する問題