Anmeldung in mehreren Klassen mit dem Modul-Namen im log
Ich will das logging-Modul anstelle von drucken für debug-Informationen und Dokumentation.
Das Ziel ist für das drucken auf der Konsole mit DEBUG-level und log in eine Datei mit dem INFO-level.
Las ich über eine Menge an Dokumentation, das Kochbuch und die anderen tutorials auf der logging-Modul, konnte aber nicht herausfinden, wie kann ich es nutzen wie ich es möchte. (Ich bin auf python25)
Ich will die Namen der Module, in denen die logs sind geschrieben in meinem logfile.
Die Dokumentation sagt, ich sollte verwenden logger = logging.getLogger(__name__)
aber wie erkläre ich den Logger verwendet in Klassen, die in anderen Modulen /Paketen, so dass Sie verwenden die gleichen Handler wie der Haupt-logger? Zu erkennen, das 'parent', die ich verwenden kann logger = logging.getLogger(parent.child)
aber Woher weiß ich, wer gerufen hat, die Klasse/Methode?`
Beispiel unten zeigt mein problem, wenn ich diese ausführe, wird die Ausgabe nur die __main__
sich anmeldet, und ignorieren Sie die Protokolle in Class
Dies ist mein Mainfile:
# main.py
import logging
from module import Class
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# create file handler which logs info messages
fh = logging.FileHandler('foo.log', 'w', 'utf-8')
fh.setLevel(logging.INFO)
# create console handler with a debug log level
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# creating a formatter
formatter = logging.Formatter('- %(name)s - %(levelname)-8s: %(message)s')
# setting handler format
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(fh)
logger.addHandler(ch)
if __name__ == '__main__':
logger.info('Script starts')
logger.info('calling class Class')
c = Class()
logger.info('calling c.do_something()')
c.do_something()
logger.info('calling c.try_something()')
c.try_something()
Modul:
# module.py
imnport logging
class Class:
def __init__(self):
self.logger = logging.getLogger(__name__) # What do I have to enter here?
self.logger.info('creating an instance of Class')
self.dict = {'a':'A'}
def do_something(self):
self.logger.debug('doing something')
a = 1 + 1
self.logger.debug('done doing something')
def try_something(self):
try:
logging.debug(self.dict['b'])
except KeyError, e:
logging.exception(e)
Ausgabe in Konsole:
- __main__ - INFO : Script starts
- __main__ - INFO : calling class Class
- __main__ - INFO : calling c.do_something()
- __main__ - INFO : calling c.try_something()
No handlers could be found for logger "module"
Außerdem: gibt es einen Weg, um den Modul-Namen wurden in den logs aufgetreten in meinem logfile, ohne Sie zu deklarieren einer neuen logger in jeder Klasse wie oben? Auch, wie dieser Weg muss ich gehen für self.logger.info()
jedes mal, wenn ich die Anmeldung etwas. Ich würde es vorziehen, zu verwenden logging.info()
oder logger.info()
in meinem ganzen code.
Ist ein global logger-vielleicht ist die richtige Antwort? Dann aber werde ich nicht Holen Sie sich die Module, in denen die Fehler auftreten in den logs...
Und meine Letzte Frage: Ist das pythonic? Oder gibt es eine bessere Empfehlung, solche Dinge zu tun rechts.
Du musst angemeldet sein, um einen Kommentar abzugeben.
In deinem main-Modul, du bist konfigurieren der logger-name
'__main__'
(oder was auch immer__name__
entspricht in Ihrem Fall), während in module.py du bist mit einem anderen logger. Sie müssen entweder zu konfigurieren-Logger pro Modul, oder Sie können konfigurieren, das root-logger (durch Konfigurationlogging.getLogger()
) in deinem main-Modul wird standardmäßig gelten für alle Holzfäller, die in Ihrem Projekt.Empfehle ich die Verwendung von Konfigurationsdateien für die Konfiguration der Logger. Dieser link sollte Ihnen eine gute Idee von guten Praktiken: http://victorlin.me/posts/2012/08/26/good-logging-practice-in-python
EDIT: mit %(module) in Ihrem formatter enthalten den Namen des Moduls in der log-Meldung.
logger.getLogger(__name__)
dann erhalten Sie die vollständige Modul-Namen (einschließlich der Paket-Hierarchie) in die log-Meldung (vorausgesetzt, Sie haben die%(name)
formatter-element). Denken Sie daran, wenn der root-logger konfiguriert ist, dann wird es gelten für alle Kinder (D. H. alle Pakete und Module).logging.getLogger(__name__)
Variante? Was muss ich eingeben in der Zeile, in meiner Klasse?__name__
von der getLogger nennen Sie in Ihrer main.py Modul oben, sollte alles so funktionieren, wie Sie wollte, ohne irgendwelche anderen änderungen (da Sie die Konfiguration der root-logger, die gilt für alle Kinder, einschließlich module.py). Versuchen Sie es, und Sie sollten verstehen, was ich meine.__name__
zu''
Solltest du einen globalen logger mit Ihrem Handler:
Dann auf jeder Modul:
logger= logging.getLogger("myapp."+__name__)
Ob Sie pro-Klasse Logger ist bis zu Ihnen - die meisten Projekte, die ich gesehen habe (höchstens) einen logger pro Modul. Mein Rat ist, wenn Sie nicht brauchen, verschiedene Handler für verschiedene Klassen, stick mit einem logger pro Modul, oder sogar ein logger pro Projekt - wenn das Projekt klein ist.
Wenn du mehr brauchst Kontext auf Ihre Protokolle, Hinweis drucken können Sie die aktuelle Funktion Namen mit
%(funcName)s
auf dem formattergetLogger(__name__)
in meine main-Datei. wenn ich''
es und die__name__
im Modul ist alles richtig dargestellt!getLogger('')
- andere Module aus Bibliotheken, die Sie verwenden könnten am Ende mit dem root-logger zu, und Sie können dann ändern Sie Ihre Handler-und Formatierer-Konfiguration. Es ist sicherer, einfach zu benutzen, ein Projekt-weit-Präfix'anyting else'
'myapp.'+__name__
jedes einzelne mal, wenn...'parentloggername+'.'+'childloggername'
,logging
denkt, Sie sind unabhängig (d.h.: nicht Eltern/Kind)