Skip to content

Latest commit

 

History

History
166 lines (136 loc) · 7.75 KB

logging.md

File metadata and controls

166 lines (136 loc) · 7.75 KB

Python Logging

Three modules: logging, logging.config, logging.handlers. Configuration can be done with function calls, a dictionary or a config file.

Overview

Logging is done by calling methods on Logger objects obtained from logging.getLogger(name). These are arranged in a hirarchy based on dot-separated components name: logger foo.bar has parent foo, which in turn has the root logger as its parent. getLogger(__name__) is the canonical way to get a logger object for the current module. (The Logger object will be created if it does not already exist.) getChild(suffix) will get/create a child of a given logger.

Calling log(lvl, msg, ...) on a Logger does the following. (debug(msg, ...) etc. are equivalent with preset lvl.)

  1. Determines if lvl is below this logger's threshold by calling isEnabledFor(lvl). The message is ignored if it's below:
  • the global disable level set by logging.disable(lvl)
  • this logger's level, if it's not NOTSET (0)
  • the first level above NOTSET for each parent logger up the tree.
  1. Creates a LogRecord object using makeRecord(...).

  2. Calls handle(record), which:

    1. Checks the Logger's disable property. If True, the record is ignored.
    2. Calls filter(record) to check with each filter on this Logger. If any filter returns False, the record is ignored.
    3. Passes the record to all of this Logger's handlers. (Individual handlers may also have their own minimum logging levels.)
    4. If propagate is True, passes the record to the handlers of each parent logger up the tree until it finds one with propagate False or reaches the root. (Note that this does not check threshold levels or filters of parent Loggers.)

Handlers and Formatters

If the root logger has no handler, calling any logging.log method will execute logging.basicConfig() to set up a StreamHandler to stderr that uses the default formatter. To set up a custom one:

  1. Choose a handler from logging.handlers and instantiate it.
  2. Optionally, instantiate a Formatter and pass it to handler.setFormatter()
  3. Call addHandler(handler) on your Logger.

Suggested formatters:

Format(fmt='{levelname}:{name}:{message}', datefmt=None, style='{')

Note that the style argument above applies only to the fmt argument, not to calls to log(msg, arg1, ...). The latter always uses % formatting for compatibility: because libraries you use may be using that form, % formatting for log() should not be removed. For more details on this, see Using particular formatting styles throughout your application.

Simple Start

import logging
logging.warning('...')          # debug, info, warning, error, critical
logging.info('x²=%s', x*x)
logging.error('Caught!', exec_info=true)    # Same as logging.exception()

# `root` is the default name of the root logger, so output is like
# WARNING:root:...

You can call logging.basicConfig() before any of the above to configure the root logger; it will have no effect after. This cannot be used to configure other Logger objects.

  • level: Minimum level to print, default WARNING. See below.
  • datefmt: Format for dates as with time.strftime().
  • format: Format string for handler; see LogRecord attributes.
  • style: Style for format, one of '%' (printf, default), '{' (str.format()), '$' (string.Template).
  • filename: Create a FileHandler with the given filename instead of a StreamHandler to stderr.
  • filemode: Default 'a'.
  • stream: Use a given stream; incompatible with filename.

Logging Levels

Messages are logged only if their level exceeds a threshold that ranges from 0 upward. Each level may have a name assigned to it; the default names are:

logging.NOTSET   =  0
logging.DEBUG    = 10
logging.INFO     = 20
logging.WARNING  = 30
logging.ERROR    = 40
logging.CRITICAL = 50
  • getLevelName(lvl): returns the name of a level, or "Level n" if no other name has been assigned.
  • addLevelName(lvl, name) sets the name of a level, overwriting any previously assigned name (including the default names).

API Reference

Call only logging.getLogger(name) to instantiate a Logger. name is usually __name__. Multiple calls with the same name return the same object. Names may be hierarchical separated by . for a parent/child relationship.

Classes:

  • LogRecord: Single log entry created by a Logger.
  • Logger: Instantiate only via logging.getLogger().
    • addHandler(handler): Adds a Handler; one Logger may have multiple Handlers.
  • Handler: Send LogRecords ≥ configured level to an output. Base class of StreamHandler, FileHandler, HTTPHandler, SMTPHandler, etc.
    • setLevel(level)
    • setFormatter(formatter): Takes a Formatter object.
  • Formatter
  • Filter

Functions:

  • logging.exception()
  • logging.config.fileConfig(fname, disable_existing_loggers),
  • logging.config.dictConfig()