logging.basicConfig()
configures the root logger. The default log level of basicConfig()
is logging.WARNING
or 30
(try print(logging.getLogger().level)
or print(logging.root.level)
).
logging.getLogger()
, logging.getLogger(None)
and logging.root
returns the same root logger.
In [26]: logging.getLogger().level
Out[26]: 30
In [27]: logging.getLogger(__name__).level
Out[27]: 0
In [28]: logging.root is logging.getLogger(), logging.root is logging.getLogger(None)
Out[28]: (True, True)
Both the logger and handler have method setLevel()
. Log level for a logger controls what levels of log messages the logger will print. Log level for a handler controls what levels of log messages the handler will handle. If a logger or handler does not call setLevel()
, the default log level is logging.NOTSET
or 0
(try print(logging.getLogger(__name__).level)
).
You program defines loggers, the root logger or application logger(s). Loggers have a hierarchy indicated by their names, for example, a.b.c
is a child of a.b
and a
and root logger. Child loggers inherit logging configurations from their parents, which is done by child loggers propagating log messages to the first parent logger whose log level is not NOTSET (0).
To explicitly configure a logger:
- create logger
- set log level for the logger (by default the log level is
logging.NOTSET
or0
, so this logger will propagate log messages up to its parent logger or parent logger's parent logger, and so on untill a parent log whose leg level is notlogging.NOTSET
) - create handler
- set log level for the handler (optional)
- create formatter
- set formater for the handler
- add handler to the logger
import logging
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# create file handler which logs even debug messages
fh = logging.FileHandler('spam.log')
fh.setLevel(logging.DEBUG)
# create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.ERROR)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
fh.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(ch)
logger.addHandler(fh)
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')