2016-07-08 8 views
0

Also, jetzt habe ich einen Prozess, der mehrere Threads hervorbringt, jeder mit seinen eigenen Instanzdaten. Ich muss kontextspezifische Informationen in jede der Logging-Anweisungen einfügen, die über die verschiedenen Methoden innerhalb der abgeleiteten Thread-Klasse aufgerufen werden (in diesem Fall ist die kontextspezifische Information die E-Mail der Person, die den zu erstellenden Thread ausgelöst hat). .Nur der erste Filter, der auf dem Logger überprüft wird

Hier ist der Filter ich derzeit

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()) 

„Runner“ in diesem Fall verwendet, ist eine Klasse, die eine Unterklasse der Thread ist, also die Fähigkeit, getName() aufzurufen.

Jetzt, für den Filter, instanziiere ich jedes Mal, wenn ein neuer Thread erstellt wird, einen neuen Filter, indem ich eine neue Instanz des Filters zur Logging-Instanz in der __init__ Methode der Runner-Klasse hinzufüge.

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

Wo _log meine globale Protokollierung Instanz ist für alle diese Fäden. Und der Filter fügt völlig in Ordnung!
Ich kann _log.filters aufrufen und jeden der einzelnen Filter sehen. Das funktioniert ganz gut.

Was nicht funktioniert ist, wenn beim Lesen der Logging-Anweisungen nur der erste Filter überprüft wird.

Ich habe Debug-Anweisungen zum Filter hinzugefügt, um zu überprüfen, was in ihm passiert. eprint ist nur eine Hilfsmethode sys.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()) 

zu drucken, wenn ich den Manager und laichen mehrere Threads starten, erhalte ich die gleiche Filterprüfung jedes Mal, immer den ersten Filter, der erstellt wurde.

Beispiel Logausgabe

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 

es überhaupt nur vergleicht sie 52-Faden, der das erste Filter ist, das erstellt wurde. Aber wenn ich alle Filter an den Logger

for fil in _log.filters: 
    print(fil.runner.getName()) 
angewendet auszudrucken

ich

Thread-52 
Thread-53 
Thread-54 

So weiß ich, dass alle Filter an den Logger angewendet werden, aber sie sind nicht alle aus irgendeinem Grund verglichen werden. Ich bekomme False für die Filtervergleichsanweisung für jede einzelne Protokollanweisung nach dem ersten Thread.

Prüft Python nur den ersten Filter? Richte ich etwas falsch ein? Fehle ich hier etwas?

Ich denke, das sollte ziemlich einfach sein, aber Pythons Logging-Dokumentation macht für mich keinen Sinn.

Wenn Sie mehr Kontext benötigen, oder wenn ich unklar bin, lass es mich wissen. Ich möchte das schaffen.Haha

Antwort

0

es herausgefunden, falls jemand jemals mit so etwas wie dies in der Zukunft (oder vielleicht auch Sie nicht, weil Sie ein besserer Programmierer als ich, haha)

für die Anmeldung in Python, nur stecken bleibt Einer der Filter muss fehlschlagen, damit die gesamte Protokollnachricht gelöscht wird. Ich dachte, es würde die Filter überprüfen und sehen, ob mindestens einer von ihnen bestanden hat, aber ich merke, wie dieser Denkprozess jetzt gebrochen ist.

Um dies zu umgehen, habe ich einen neuen Handler für jeden erzeugten Thread instanziiert und eine neue Instanz des Filters auf diesen Handler angewendet, und dann habe ich den Handler auf die _log Instanz angewendet.

Jetzt hat _log viele Handler und jeder dieser Handler hat einen einzigen Filter. Die Logging-Anweisung überprüft jeden der Handler und nur derjenige mit dem richtigen Filter wird gesendet. :)

Es funktioniert!