2014-03-06 10 views
11

Ich versuche, die beste Vorgehensweise für die Anmeldung in Python über mehrere Module herauszufinden. Ich sehe hier: http://docs.python.org/2/howto/logging#logging-from-multiple-modules zur Verwendung der Root-Logger, um über mehrere Module zu protokollieren. Wie der Link jedoch zeigt, können Sie nicht sagen, woher in Ihrer Anwendung Ihre Nachrichten kommen, da sie alle den Namen "root" anzeigen.Ist es besser, root Logger oder named Logger in Python zu verwenden

Es scheint mir, gibt es zwei Möglichkeiten (unter Annahme meine Module nicht in einer Paketstruktur sind, aber sie sind nur ein Haufen von Modulen im selben Ordner):

1) Verwenden Sie den Root-Logger wie in der Beispiel, aber die Log-Formatierung ändern Sie den Dateinamen enthalten:

# myapp.py 
import logging 
import mylib 

def main(): 
    logging.basicConfig(format='%(asctime)s %(filename)s %(levelname)s: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO) #filename='myapp.log', 
    logging.info('Started') 
    mylib.do_something() 
    logging.info('Finished') 

if __name__ == '__main__': 
    main() 

#mylib.py 
import logging 

def do_something(): 
    logging.info('Do something') 




In [4]: import myapp 

In [5]: myapp.main() 
03/06/2014 12:22:07 PM myapp.py INFO: Started 
03/06/2014 12:22:07 PM mylib.py INFO: Do something 
03/06/2014 12:22:07 PM myapp.py INFO: Finished 

2) verwenden Sie ein root-Logger im Haupt App aber eine benannte Logger in der Submodule, und verwenden Sie ‚name‘ anstelle von ‚Dateiname‘ im Protokoll format:

# myapp.py 
import logging 
import mylib 

def main(): 
    #logging.basicConfig(format='%(asctime)s %(filename)s %(levelname)s: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO) #filename='myapp.log', 
    logging.basicConfig(format='%(asctime)s %(name)s %(levelname)s: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO) #filename='myapp.log', 
    logging.info('Started') 
    mylib.do_something() 
    logging.info('Finished') 

if __name__ == '__main__': 
    main() 

#mylib.py 
import logging 

def do_something(): 
    #logging.info('Do something') 
    logger = logging.getLogger(__name__) 
    logger.info('Do something') 



In [3]: import myapp 

In [4]: myapp.main() 
03/06/2014 12:27:29 PM root INFO: Started 
03/06/2014 12:27:29 PM mylib INFO: Do something 
03/06/2014 12:27:29 PM root INFO: Finished 

Antwort

7

Vinay Sajip (Maintainer des Logging-Modul) blockt den recommendation here die auf Ihre Option # 2 ähnlich ist, mit der Ausnahme, dass Sie einen Namen Logger überall nutzen können, auch in myapp:

import logging 
import mylib 
logger = logging.getLogger(__name__) 

def main(): 
    logging.basicConfig(format='%(asctime)s %(module)s %(levelname)s: %(message)s', 
         datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.INFO) 
    logger.info('Started') 
    mylib.do_something() 
    logger.info('Finished') 

if __name__ == '__main__': 
    main() 

die

03/06/2014 12:59:25 PM myapp INFO: Started 
03/06/2014 12:59:25 PM mylib INFO: Do something 
03/06/2014 12:59:25 PM myapp INFO: Finished 
ergibt

Beachten Sie, dass, wenn Sie %(module)s statt %(name)s verwenden, Sie myapp dann erhalten, wo, bevor Sie bekam root oder myapp.py oder __main__.

Diese Symmetrie - immer logger verwenden - kann besonders nützlich sein, wenn myapp manchmal als ein Skript aufgerufen und manchmal als ein Modul importiert wird.

+0

Danke! Ich habe das versucht, und es funktioniert, aber ich verstehe nicht warum. (Beide Logger in myapp und mylib namens "\ __ name__".) \ __ name__ in myapp ist "myapp", wenn myapp wie in meinem Beispiel importiert wird. \ __ name__ in mylib ist "mylib" Also, in jeder Datei, wenn logger = logging.getLogger (\ __ name__), erstellen sie nicht zwei verschiedene Logger? Funktioniert es, weil die Ausgabe von jedem einzelnen Logger immer noch an den Root-Logger und dann an die Konsole weitergegeben wird? – bobo5645

+0

Kannst du auch auf deinen letzten Kommentar eingehen, dass "logger" immer dann nützlich ist, wenn myapp manchmal als Skript aufgerufen oder als Modul importiert wird? Du meinst logger = logging.getLogger (..) ist dafür besser als nur root logger direkt zu verwenden: logging.info ("..")? – bobo5645

+0

Ja, Sie erhalten zwei verschiedene Logger. [Dieses Flowchart] (http://docs.python.org/2/howto/logging.html#logging-flow) zeigt Logger (standardmäßig) propagieren Datensätze an Parent-Logger. So erhalten die Handler des Root-Loggers eine Chance, den Datensatz zu behandeln. – unutbu

Verwandte Themen