Logging in Python
Table of Contents
- Introduction to logging module and severity levels
- Using integers to denote severity levels
- Logging to a file: filename & filemode
- Formatting log messages: format & datefmt
logging in Python
Introduction to logging module and severity levels§
Logging in Python: The standard library logging helps you to log events of different severities to a file or the standard output in interpreter. This is particularly helpful in large applications where you would like to record events as they occur for future reference. There are five severity levels defined in the logging module. These are, in ascending order:
- DEBUG: diagnostic breadcrumb messages
- INFO: general information
- WARNING: non-fatal & non-serious issues
- ERROR: errors, may be serious
- CRITICAL: fatal errors
These severity levels have corresponding functions in the logging module. These are debug(), info(), warning(), error() & critical(). Each of these methods take a message in the form of a string.
Let's take a look at a basic example. The following statements log 3 events to the standard output in interpreter.
>>> import logging >>> logging.basicConfig(level=logging.INFO) >>> logging.debug('A debugging message here.') # prints nothing, since we have set level to INFO & above. >>> logging.info('An informative message here.') INFO:root:An informative message here. >>> logging.warning('A warning message here.') WARNING:root:A warning message here.
Two things to note here: basicConfig() & the word 'root' in logging messages. The basicConfig() function helps you to configure your log messages by providing specifications such as the minimum severity of messages to be logged, the format in which messages are logged etc. We will talk about this function more as we go along. Here, the level specifies the minimum severity level of messages to be printed or logged. The default value of this argument is WARNING i.e. if we do not specify the level argument at all, only messages wrapped in warning(), error() & critical() get logged.
The 'root' is the default logger instance. You can create a new logger instance using the getLogger() function.
>>> import logging >>> logger = logging.getLogger('myLog') >>> logging.basicConfig(level=logging.DEBUG) >>> logger.debug('A debugging message here.') DEBUG:myLog:A debugging message here. >>> logger.info('An informative message here.') INFO:myLog:An informative message here. >>> logger.warning('A warning message here.') WARNING:myLog:A warning message here.
It is common practice to use the dunder file attrubute __file__ to denote the logger instance i.e. logger = logging.getLogger(__file__).
Using integers to denote severity levels§
You can use integers to specify the severity level as well, since the severity levels defined in the logging module actually resolve to integers.
>>> logging.DEBUG 10 >>> logging.INFO 20 >>> logging.WARNING 30 >>> logging.ERROR 40 >>> logging.CRITICAL 50 >>> logging.basicConfig(level=20) >>> logging.debug('A debugging message here.') >>> logging.info('An informative message here.') INFO:root:An informative message here. >>> logging.warning('A warning message here.') WARNING:root:A warning message here.
Logging to a file: filename & filemode§
In order to log the messages to a file instead of standard output of interpreter, specify a file name in the filename argument of basicConfig() function.
>>> logging.basicConfig(level = 20, filename = 'myLog.log') >>> logging.debug('A debugging message here.') >>> logging.info('An informative message here.') >>> logging.warning('A warning message here.')
By default, the output is appended to the specified file. In order to erase all contents of the log when the script/application is run, set the filemode to 'w'.
logging.basicConfig(level = 20, filename = 'myLog.log', filemode = 'w')
Formatting log messages: format & datefmt§
You can customize the way your messages are logged by specifying log record attributes in the format of basicConfig() function.
## WITHOUT THE format ARGUMENT ## >>> import logging >>> logging.basicConfig(level = 10) >>> logging.debug('A debugging message here.') DEBUG:root:A debugging message here. >>> logging.info('An informative message here.') INFO:root:An informative message here. >>> logging.warning('A warning message here.') WARNING:root:A warning message here. ## WITH THE format ARGUMENT ## >>> import logging >>> logging.basicConfig(level = 10, format = '%(asctime)s %(levelname)s %(message)s') >>> logging.debug('A debugging message here.') 2017-02-18 04:40:38,420 DEBUG A debugging message here. >>> logging.info('An informative message here.') 2017-02-18 04:40:41,274 INFO An informative message here. >>> logging.warning('A warning message here.') 2017-02-18 04:40:42,773 WARNING A warning message here.
The asctime attribute gives us human readable time of the instant when the message was logged. levelname is the logging severity level and message is the message itself.
To view the complete list of log record attributes you can use, click here.
In order to customize the time part of chosen format, you can use directives used in datetime module and specify them in the datefmt argument of basicConfig function.
>>> logging.basicConfig(level = 10, format = '%(asctime)s %(levelname)s %(message)s', datefmt = "%d/%m/%y") >>> logging.debug('A debugging message here.') 18/02/17 DEBUG A debugging message here. >>> logging.basicConfig(level = 10, format = '%(asctime)s %(levelname)s %(message)s', datefmt = "%A %d %B %Y %H:%M:%S") >>> logging.debug('A debugging message here.') Saturday 18 February 2017 04:49:21 DEBUG A debugging message here.
That's it for this one! Now you can use logging in your projects for recording events as they happen and catching bugs. Cheers!