How do I change the format of a Python log message on a per-logger basis?
Solution 1
Try this
import logging
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# create file handler that logs debug and higher level 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.warn('warn message')
logger.error('error message')
logger.critical('critical message')
See http://docs.python.org/howto/logging-cookbook.html#multiple-handlers-and-formatters for more information
Solution 2
You have to create or use an existing subclass of logging.Handler
and call the setformatter()
method of an instance thereof with an instance of a custom subclass of logger.Formatter
. If you set the formatter for a handler that was already attached to the logger you want to modify the output of, you are fine, otherwise you have to retrieve a logger object with logging.getLogger()
and call its addHandler()
method with the instance of your handler class that you set the formatter on as the argument.
Ricardo Altamirano
Originally from Nicaragua, educated in Edinburgh and the USA, and now living primarily in London. Useful questions and answers Stack Overflow Debugging CREATE TABLE statements Logging in Python Simple string formatting in Python Reference types in C# String compression in C# using Gzip Meta Stack Overflow Book recommendation questions Answering old questions with a solution in the comments IT Security Cryptographically secure random strings in PHP LaTeX Fitting a table on a page through rotation StackExchange Flair
Updated on August 13, 2020Comments
-
Ricardo Altamirano over 3 years
After reading the documentation on
logging
, I know I can use code like this to perform simple logging:import logging def main(): logging.basicConfig(filename="messages.log", level=logging.WARNING, format='%(filename)s: ' '%(levelname)s: ' '%(funcName)s(): ' '%(lineno)d:\t' '%(message)s') logging.debug("Only for debug purposes\n") logging.shutdown() main()
However, I realised I don't know how to change the format of log messages on a per-logger basis, since
basicConfig
is a module-level function. This code works for creating different loggers with different levels, names, etc. but is there a way to change the format of those log messages on a per-logger basis as well, in a way similar tobasicConfig
?import inspect import logging def function_logger(level=logging.DEBUG): function_name = inspect.stack()[1][3] logger = logging.getLogger(function_name) logger.setLevel(level) logger.addHandler(logging.FileHandler("{0}.log".format(function_name))) return logger def f1(): f1_logger = function_logger() f1_logger.debug("f1 Debug message") f1_logger.warning("f1 Warning message") f1_logger.critical("f1 Critical message") def f2(): f2_logger = function_logger(logging.WARNING) f2_logger.debug("f2 Debug message") f2_logger.warning("f2 Warning message") f2_logger.critical("f2 Critical message") def main(): f1() f2() logging.shutdown() main()