Logging in Python
Logging in Python¶
Python has a very powerful logging system. Adding logging to a Python program is as simple as:
import logging
logger = logging.getLogger('__name__')
def function_that_logs(x, y):
logger.info(f"I was called with x={x}, y={y}")
However, calling function_that_logs
won't print the logged message anywhere yet:
function_that_logs(12, 13)
This is because unless explicitly enabled, python ignores logging calls. Otherwise calling codes would be inundated with logging messages from various libraries. There are a few steps to do before our logged message gets anywhere.
# Set the logger level. Anything logged with level lower than DEBUG will be ignored.
logger.setLevel(logging.DEBUG)
# Now add a handler to our logger. StreamHandler prints to stderr
handler = logging.StreamHandler()
# Now the handler's level must be set too.
handler.setLevel(logging.DEBUG)
# Add the handler to the logger
logger.addHandler(handler)
function_that_logs(12, 13)
Finally, our logged message appears. A logger
can have multiple handler
s in Python: logging
module contains many kinds of handlers, e.g. HTTPHandler
(sends logs to a web server), SMTPHandler
(sends the log via email) etc.
Custom formatters¶
We might sometimes want some additional information to be logged alongwith the message, for example the time the log was created. This can be achieved by setting the formatter
of our log handler:
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(funcName)s - %(message)s')
handler.setFormatter(formatter)
logger.handlers = []
logger.addHandler(handler)
Where do the properties like asctime
or funcName
come from? They are all attributes of the Logrecord objects. On each logging call, such a LogRecord
object is created, and they contain a lot of information including the calling code's module name, filepath, line number etc.
class CustomFormatter(logging.Formatter):
def format(self, record):
return "Hello"
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
formatter = CustomFormatter()
handler.setFormatter(formatter)
logger.addHandler(handler)
function_that_logs(12, 13)