2013-03-04 17 views
11

Dies ist mein Szenario: Ich möchte die Aktivität meines Moduls protokollieren. Dies muss abhängig von der ausgeführten Methode (sagen wir INPUT und OUTPUT) in zwei verschiedenen Dateien erfolgen.Python protokolliert mehrere Dateien mit demselben Logger

So habe ich zwei Handler, jeder Punkt auf eine andere Datei (my_in_.log & my_out_.log), mit dem gleichen Protokolllevel. Ich würde gerne wissen, ob ich den gleichen Logger verwenden kann, um dies zu erreichen, oder ich muss zwei Logger definieren. Meine Config ist:

[loggers] 
keys=root, my_log 

[handlers] 
keys=my_in_hand, my_out_hand 

[formatters] 
keys=generic_form 


... 


[logger_my_log] 
level=NOTSET 
handlers=my_in_hand, my_out_hand 
qualname=ws_log 

[handler_my_in_hand] 
class=handlers.TimeRotatingFileHandler 
level=NOTSET 
formatter=generic_form 
args=('my_in_.log', 'h', 1, 0, None, False, True) 

[handler_my_out_hand] 
class=handlers.TimeRotatingFileHandler 
level=NOTSET 
formatter=generic_form 
args=('my_out_.log', 'h', 1, 0, None, False, True) 

Muss ich einen Logger pro Handler/Ziel definieren? (weil ich verschiedene Informationen in verschiedenen Dateien protokollieren möchte) Gibt es eine Möglichkeit, dem Logger anzuzeigen, welcher Handler das tun wird? Ich meine, ich habe zwei Handler für einen Logger und wähle dann nur einen Handler, um eine Methode zu protokollieren.

Vielen Dank!

Antwort

3

Schließlich habe ich beschlossen, zwei Loggern zu definieren, denn:

  • Sie für verschiedene purposses sind. In meinem Fall protokolliert man die Eingabeanforderung an einen Webdienst und die andere protokolliert die Antwort. Und sie verwenden verschiedene Dateien dazu

  • Ich benutze eine Logging-Konfigurationsdatei, in einem frontalen Web-Service. Hinzufügen/Entfernen von Handlern vor dem Protokollieren von Nachrichten ist nicht der richtige Ansatz, wie @ Mike sagte. Danke auch an @drekyn!

Hier ist meine Logging-Konfigurationsdatei, nur als Referenz, wenn jemand Interesse an:

[loggers] 
keys=root, ws_in_log, ws_out_log 

[handlers] 
keys=consoleHandler, ws_in_hand, ws_out_hand 

[formatters] 
keys=generic_form 

[logger_root] 
handlers=consoleHandler 
level=NOTSET 

[logger_ws_in_log] 
level=NOTSET 
handlers=ws_in_hand 
qualname=ws_in_log 

[logger_ws_out_log] 
level=NOTSET 
handlers=ws_out_hand 
qualname=ws_out_log 

[handler_ws_in_hand] 
class=logging.handlers.TimedRotatingFileHandler 
level=NOTSET 
formatter=generic_form 
args=('/path/ws_in_.log', 'h', 1, 0, None, False, True) 

[handler_ws_out_hand] 
class=logging.handlers.TimedRotatingFileHandler 
level=NOTSET 
formatter=generic_form 
args=('/path/em/ws_out_.log', 'h', 1, 0, None, False, True) 

[handler_consoleHandler] 
class=StreamHandler 
level=DEBUG 
formatter=generic_form 
args=(sys.stdout,) 

[formatter_generic_form] 
format='%(asctime)s - %(levelname)s - %(message)s' 
datefmt='%Y-%m-%d %H:%M:%S' 
class= 

Sie sehen!

7

Sie sollten einen Handler für jedes Ziel instanziieren, an den Sie Ihr Protokoll senden möchten, und dann die beiden Handler zu Ihrem Logger hinzufügen. Folgendes sollte funktionieren (habe es allerdings nicht getestet):

logger = logging.getLogger() 
handler1 = logging.TimedRotatingFileHandler() 
handler2 = logging.TimedRotatingFileHandler() 
logger.addHandler(handler1) 
logger.addHandler(handler2) 

Natürlich alle Ihre Konfiguration und Formatierungsoptionen hinzufügen, die Sie benötigen. Im Grunde ist es nur, um Ihnen zu zeigen, dass wenn Sie den Logging-Handler instanziieren, Sie es dem Logger hinzufügen können. Ab diesem Zeitpunkt werden Ihre Protokolldatensätze an alle dem Logger hinzugefügten Handler gesendet.

+0

Vielleicht bin ich nicht klar: Ich will nicht meine Aufzeichnungen einzuloggen an den Logger jeder Handler ** ** hinzugefügt. Was ich will, ist auszuwählen, welcher Handler den Datensatz protokollieren wird, dh ein Logger -> zwei Handler, aber wählen Sie, welchem ​​Ziel der Datensatz zugewiesen wird. Verwenden Sie den gleichen Logger mit verschiedenen Handlern, aber einige Datensätze werden von einem Handler protokolliert und einige mit anderen ... Ist das möglich oder muss ich andere Logger definieren? VIELEN DANK! :) –

+1

@ AlbertoMegía Sie sollten Ihre eigene Methode definieren, die als Argument das Protokollziel verwendet und intern den richtigen Handler für die Protokollnachricht verwendet. – mike

+0

Also @mike Sie meinen, ich muss Logger-Handler hinzufügen und entfernen, um es in Runtime auswählen? Dies ist vielleicht nicht meine beste Option, da dieses Modul meine Frontalansicht in einem Webdienst ist ... bei jeder Anforderung müsste ich Handler wechseln ...: S –

3

, was Sie wollen, ist zu

  1. 2 NON ROOT-Logger erstellen.
  2. Make-Handler für jeden, zeigen Sie auf verschiedene Datei
  3. Add-Handler entsprechenden Logger

    logger1 = logging.getLogger('general_logger') 
    logger2 = logging.getLogger('some_other_logger') 
    
    log_handler1 = logging.handlers.RotatingFileHandler(file_1, *args) 
    log_handler2 = logging.handlers.RotatingFileHandler(file_2, *args) 
    
    logger1.addHandler(log_handler1) 
    logger2.addHandler(log_handler2) 
    

dann

logger1.info("this will be logged to file_1 ") 
    logger2.info("this will be logged to file_2 ") 

Bitte beachten Sie, dass, wenn Sie einen ROOT-Logger erstellen und Ein anderer Logger, Root Logger protokolliert alles, was dieser andere Controller zu protokollieren versucht.

Mit anderen Worten, wenn

root_logger = logging.getLogger() 
    logger2 = logging.getLogger('some_other_logger') 

    root_log_handler = logging.handlers.RotatingFileHandler(file_1, *args) 
    log_handler2 = logging.handlers.RotatingFileHandler(file_2, *args) 

    root_logger.addHandler(root_log_handler) 
    logger2.addHandler(log_handler2) 

dann

root_logger.info("this will be logged to file_1 ") 
    logger2.info("this will be logged to file_1 AND file_2 ")