18.5. Logging Handlers

  • StreamHandler - Output to Stdout or Stderr

  • FileHandler - Output to file

  • RotatingFileHandler - Output to file with rotation based on file size

  • WatchedFileHandler - Output to file with monitoring for external changes

  • TimedRotatingFileHandler - Output to file with rotation based on time

  • SocketHandler - Output to TCP/IP socket

  • DatagramHandler - Output to UDP socket

  • HTTPHandler - Output to HTTP server

  • SMTPHandler - Output to email address via SMTP

  • SysLogHandler - Output to Unix syslog daemon

  • NTEventLogHandler - Output to Windows NT/2000/XP event log

  • MemoryHandler - Output to memory buffer

  • QueueHandler - Output to queue

  • NullHandler - Do not display output

18.5.1. Stdout and Stderr

  • StreamHandler - instances send messages to streams (file-like objects).

18.5.2. File

  • FileHandler - instances send messages to disk files.

  • WatchedFileHandler instances watch the file they are logging to. If the file changes, it is closed and reopened using the file name. This handler is only useful on Unix-like systems; Windows does not support the underlying mechanism used.

  • BaseRotatingHandler is the base class for handlers that rotate log files at a certain point. It is not meant to be instantiated directly. Instead, use RotatingFileHandler or TimedRotatingFileHandler.

  • RotatingFileHandler instances send messages to disk files, with support for maximum log file sizes and log file rotation.

  • TimedRotatingFileHandler instances send messages to disk files, rotating the log file at certain timed intervals.

18.5.3. Network

  • SocketHandler - instances send messages to TCP/IP sockets. Since 3.4, Unix domain sockets are also supported.

  • DatagramHandler instances send messages to UDP sockets. Since 3.4, Unix domain sockets are also supported.

  • SMTPHandler instances send messages to a designated email address.

  • HTTPHandler instances send messages to an HTTP server using either GET or POST semantics.

18.5.4. System Log

  • SysLogHandler instances send messages to a Unix syslog daemon, possibly on a remote machine.

  • NTEventLogHandler instances send messages to a Windows NT/2000/XP event log.

18.5.5. Memory

  • MemoryHandler instances send messages to a buffer in memory, which is flushed whenever specific criteria are met.

  • QueueHandler instances send messages to a queue, such as those implemented in the queue or multiprocessing modules.

18.5.6. Dummy

  • NullHandler instances do nothing with error messages. They are used by library developers who want to use logging, but want to avoid the 'No handlers could be found for logger XXX' message which can be displayed if the library user has not configured logging. See Configuring Logging for a Library for more information.

18.5.7. Log Colors

>>> import logging
>>>
>>>
>>> class LogFormatter(logging.Formatter):
...     COLORS = {
...         'CRITICAL': '\033[91;1m',
...         'ERROR': '\033[91m',
...         'INFO': '\033[36m',
...         'WARNING': '\033[33m',
...         'DEBUG': '\033[32m',
...         'RESET': '\033[0m'
...     }
...
...     def format(self, record):
...         message = super().format(record)
...         reset = self.COLORS['RESET']
...         color = self.COLORS[record.levelname]
...         return f"{color}{message}{reset}"
>>>
>>>
>>> handler = logging.StreamHandler()
>>> handler.setFormatter(LogFormatter('{levelname} {message}', style='{'))
>>>
>>> log = logging.getLogger('myapp')
>>> log.addHandler(handler)
>>> log.setLevel(logging.DEBUG)
>>>
>>> log.critical('This is a log message')
>>> log.error('This is a log message')
>>> log.info('This is a log message')
>>> log.warning('This is a log message')
>>> log.debug('This is a log message')

18.5.8. Datetime Conversion

  • Server has different timezone than the users

  • Server timezone is UTC

  • User timezone is (e.g. Poland)

>>> import logging
>>> from datetime import datetime
>>> from zoneinfo import ZoneInfo
>>>
>>>
>>> UTC = ZoneInfo('UTC')
>>> LOCAL = ZoneInfo('Poland')
>>>
>>> class LogFormatter(logging.Formatter):
...     def format(self, record):
...         utc = datetime.fromtimestamp(record.created, tz=UTC)
...         local = utc.astimezone(LOCAL)
...         message = super().format(record)
...         return f"UTC: {utc:%Y-%m-%d %H:%M}, Local: {local:%Y-%m-%d %H:%M}, {message}"
>>>
>>>
>>> handler = logging.StreamHandler()
>>> handler.setFormatter(LogFormatter('{levelname} {message}', style='{'))
>>>
>>> log = logging.getLogger('myapp')
>>> log.addHandler(handler)
>>> log.setLevel(logging.DEBUG)
>>>
>>> log.critical('This is a log message')
>>> log.error('This is a log message')
>>> log.info('This is a log message')
>>> log.warning('This is a log message')
>>> log.debug('This is a log message')

18.5.9. Further Reading