Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python logging: Different formatters for the same log file

Tags:

python

logging

I am new to the python logging module. I am trying to write to the logs in html format. I wanted to write all the logs to the same file. All the INFO logs will not have timestamps and all the other severity levels will have timestamps in the logs. How do I do this? I have seen examples in the python logging cookbooks but it shows how do that in multiple destinations. I want to know if there is a way in which I can specify different formatters based on the severity level.

https://docs.python.org/2/howto/logging-cookbook.html#logging-to-multiple-destinations

like image 678
Pradeep Avatar asked Feb 20 '15 18:02

Pradeep


1 Answers

Yes, this is possible, and I do this sort of thing fairly regularly. I'm often surprised this isn't given more often as an example in the documentation. One way you can set up something like this to create a custom Formatter that uses a different format depending on the level of the log message. There are several ways you could go about it. This particular example is a bit hacky, but would allow reusing most the code in the Formatter base class, just by wrapping multiple formatters and selecting the one to use based on the log level:

class LevelFormatter(logging.Formatter):
    def __init__(self, fmt=None, datefmt=None, level_fmts={}):
        self._level_formatters = {}
        for level, format in level_fmts.items():
            # Could optionally support level names too
            self._level_formatters[level] = Formatter(fmt=format, datefmt=datefmt)
        # self._fmt will be the default format
        super(LevelFormatter, self).__init__(fmt=fmt, datefmt=datefmt)

    def format(self, record):
        if record.levelno in self._level_formatters:
            return self._level_formatters[record.levelno].format(record)

        return super(LevelFormatter, self).format(record)

You would then use this like:

formatter = LevelFormatter(fmt='<default log format>', level_fmts={logging.INFO: '<format string for info>'})
handler.setFormatter(formatter)

That's just one approach you could iterate on. One could easily come up with others.

like image 91
Iguananaut Avatar answered Nov 15 '22 17:11

Iguananaut