Logging-Beispiele#
Erstellen einer Log-Datei#
[1]:
import logging
logging.warning('This is a warning message')
logging.critical('This is a critical message')
logging.debug('debug')
WARNING:root:This is a warning message
CRITICAL:root:This is a critical message
Logging-Ebenen#
Ebene |
Beschreibung |
---|---|
|
Das Programm wurde angehalten |
|
Ein schwerwiegender Fehler ist aufgetreten |
|
Ein Hinweis darauf, dass etwas Unerwartetes passiert ist (Standardstufe) |
|
Bestätigung, dass die Dinge wie erwartet funktionieren. |
|
Detaillierte Informationen, die in der Regel nur bei der Diagnose von Problemen von Interesse sind. |
Setzen der Logging-Ebene#
[2]:
import logging
logging.basicConfig(filename="example.log", filemode="w", level=logging.INFO)
logging.info("Informational message")
logging.error("An error has happened!")
ERROR:root:An error has happened!
Erstellen eines Logger-Objekts#
[3]:
import logging
logging.basicConfig(filename="example.log")
logger = logging.getLogger("example")
logger.setLevel(logging.INFO)
try:
raise RuntimeError
except Exception:
logger.exception("Error!")
ERROR:example:Error!
Traceback (most recent call last):
File "/var/folders/f8/0034db6d78s5r6m34fxhpk7m0000gp/T/ipykernel_7239/1794580270.py", line 8, in <module>
raise RuntimeError
RuntimeError
Ausnahmen (engl.: exceptions) loggen#
[4]:
try:
1 / 0
except ZeroDivisionError:
logger.exception("You can’t do that!")
ERROR:example:You can’t do that!
Traceback (most recent call last):
File "/var/folders/f8/0034db6d78s5r6m34fxhpk7m0000gp/T/ipykernel_7239/760044062.py", line 2, in <module>
1 / 0
ZeroDivisionError: division by zero
Logging-Handler#
Handler-Typen#
Handler |
Beschreibung |
---|---|
|
|
|
für das Schreiben auf die Festplatte |
|
unterstützt die Protokollrotation |
|
unterstützt die Rotation von Protokolldateien auf der Festplatte in bestimmten Zeitabständen |
|
sendet Logging-Ausgaben an einen Netzwerk-Socket |
|
unterstützt das Senden von Logging-Nachrichten an eine E-Mail-Adresse über SMTP |
Siehe auch:
Weitere Handler können gefunden werden unter Logging handlers
StreamHandler#
[5]:
import logging
logger = logging.getLogger('stream_logger')
logger.setLevel(logging.INFO)
console = logging.StreamHandler()
logger.addHandler(console)
logger.info("This is an informational message")
This is an informational message
INFO:stream_logger:This is an informational message
SMTPHandler#
[6]:
import logging
import logging.handlers
logger = logging.getLogger("email_logger")
logger.setLevel(logging.INFO)
fh = logging.handlers.SMTPHandler('localhost',
fromaddr='python-log@localhost',
toaddrs=['logs@cusy.io'],
subject='Python log')
logger.addHandler(fh)
logger.info("This is an informational message")
Message: 'This is an informational message'
Arguments: ()
INFO:email_logger:This is an informational message
Log-Formattierung#
Mit Formatierern könnt ihr den Log-Meldungen Formatierungen hinzufügen.
[7]:
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
Neben %(asctime)s
, %(name)s
und %(message)s
findet ihr noch weitere Attribute in LogRecord attributes.
[8]:
import logging
logger = logging.getLogger('stream_logger')
logger.setLevel(logging.INFO)
console = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
console.setFormatter(formatter)
logger.addHandler(console)
logger.info("This is an informational message")
This is an informational message
2021-12-12 21:20:55,834 - stream_logger - This is an informational message
INFO:stream_logger:This is an informational message
Bemerkung:
Das Logging-Modul ist thread-sicher. Logging funktioniert jedoch möglicherweise nicht in asynchronen Kontexten. In solchen Fällen könnt ihr jedoch den QueueHandler verwenden.
Siehe auch:
Logging an mehrere Handler#
[9]:
import logging
def log(path, multipleLocs=False):
logger = logging.getLogger("Example_logger_%s" % fname)
logger.setLevel(logging.INFO)
fh = logging.FileHandler(path)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
if multipleLocs:
console = logging.StreamHandler()
console.setLevel(logging.INFO)
console.setFormatter(formatter)
logger.addHandler(console)
logger.info("This is an informational message")
try:
1 / 0
except ZeroDivisionError:
logger.exception("You can’t do that!")
logger.critical("This is a no-brainer!")
Logging konfigurieren#
Siehe auch:
… in einer INI-Datei#
Im folgenden Beispiel wird die Datei development.ini
in diesem Verzeichnis geladen:
[loggers]
keys=root
[handlers]
keys=stream_handler
[formatters]
keys=formatter
[logger_root]
level=DEBUG
handlers=stream_handler
[handler_stream_handler]
class=StreamHandler
level=DEBUG
formatter=formatter
args=(sys.stderr,)
[formatter_formatter]
format=%(asctime)s %(name)-12s %(levelname)-8s %(message)s
[11]:
from logging.config import fileConfig
import logging
import logging.config
logging.config.fileConfig('development.ini')
logger = logging.getLogger("example")
logger.info("Program started")
logger.info("Done!")
Pro:
Möglichkeit, die Konfiguration während des Betriebs zu aktualisieren, indem die Funktion
logging.config.listen()
verwendet wird um an einem Socket zu lauschen.In verschiedenen Umgebungen können unterschiedliche Konfigurationen verwendet werden, also z.B. kann in der
development.ini
DEBUG
als Log-Level angegeben werden, während in derproduction.ini
WARN
verwendet wird.
Con:
Weniger Kontrolle z.B. gegenüber benutzerdefinierten Filtern oder Logger, die im Code konfiguriert sind.
… in einer dictConfig#
[12]:
import logging
import logging.config
dictLogConfig = {
"version":1,
"handlers":{
"fileHandler":{
"class":"logging.FileHandler",
"formatter":"exampleFormatter",
"filename":"dict_config.log"
}
},
"loggers":{
"exampleApp":{
"handlers":["fileHandler"],
"level":"INFO",
}
},
"formatters":{
"exampleFormatter":{
"format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
}
}
}
[13]:
logging.config.dictConfig(dictLogConfig)
logger = logging.getLogger("exampleApp")
logger.info("Program started")
logger.info("Done!")
2021-12-12 21:22:14,326 exampleApp INFO Program started
2021-12-12 21:22:14,329 exampleApp INFO Done!
Pro:
Aktualisieren während des Betriebs
Con:
Weniger Kontrolle als beim Konfigurieren eines Loggers im Code
… direkt im Code#
[14]:
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
Magic Commands#
Befehl |
Beschreibung |
---|---|
|
Startet das Logging irgendwo in einer Session |
|
|
Wenn kein Name angegeben wird, wird |
|
|
|
* |
|
* |
|
* |
|
* |
|
* |
|
Optionen: |
|
* |
|
* |
|
* |
|
* |
|
|
Neustart des Logging |
|
Temporäres Beenden des Logging |
Pro:
Vollständige Kontrolle über die Konfiguration
Con:
Änderungen in der Konfiguration erfordern eine Änderung des Quellcodes
Logs rotieren#
[15]:
import logging
import time
from logging.handlers import RotatingFileHandler
def create_rotating_log(path):
logger = logging.getLogger("Rotating Log")
logger.setLevel(logging.INFO)
handler = RotatingFileHandler(path, maxBytes=20,
backupCount=5)
logger.addHandler(handler)
for i in range(10):
logger.info("This is an example log line %s" % i)
time.sleep(1.5)
if __name__ == "__main__":
log_file = "rotated.log"
create_rotating_log(log_file)
2021-12-12 21:22:33,962 Rotating Log INFO This is an example log line 0
2021-12-12 21:22:33,962 Rotating Log INFO This is an example log line 0
2021-12-12 21:22:35,471 Rotating Log INFO This is an example log line 1
2021-12-12 21:22:35,471 Rotating Log INFO This is an example log line 1
Logs zeitgesteuert rotieren#
[ ]:
import logging
import time
from logging.handlers import TimedRotatingFileHandler
def create_timed_rotating_log(path):
""""""
logger = logging.getLogger("Rotating Log")
logger.setLevel(logging.INFO)
handler = TimedRotatingFileHandler(path,
when="s",
interval=5,
backupCount=5)
logger.addHandler(handler)
for i in range(6):
logger.info("This is an example!")
time.sleep(75)
if __name__ == "__main__":
log_file = "timed_rotation.log"
create_timed_rotating_log(log_file)
2021-12-12 21:22:58,287 Rotating Log INFO This is an example!
2021-12-12 21:22:58,287 Rotating Log INFO This is an example!
Erstellen eines Logging-Dekorators#
Siehe auch:
Einen Logging-Filter erstellen#
[ ]:
import logging
import sys
class ExampleFilter(logging.Filter):
def filter(self, record):
if record.funcName == 'foo':
return False
return True
logger = logging.getLogger('filter_example')
logger.addFilter(ExampleFilter())
def foo():
"""
Ignore this function’s log messages
"""
logger.debug('Message from function foo')
def bar():
logger.debug('Message from bar')
if __name__ == '__main__':
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
foo()
bar()