Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create logger that prefixes log messages

Tags:

python

logging

Let's say I have a client and server class:

import logging

class Client:
    def __init__(self, name):
        self.logger = logging.getLogger(self.__class__.__name__)
        self.name = name

    def foo(self):
        self.logger.warn('[%s] foo', self.name)

class Server:
    def __init__(self):
        self.logger = logging.getLogger(self.__class__.__name__)

    def bar(self):
        self.logger.warn('bar')

How could I make a logger for the client that will take care of the [self.name] prefix magically? The only Idea I have would be to set a global format including %(client)-prefix and using a custom filter for the Client. This seems unecessary complicated and global. I feel like there must be a simple way that I just don't see.

like image 391
Zulan Avatar asked May 02 '15 12:05

Zulan


People also ask

What is logger logging getLogger (__ Name __)?

getLogger(name) is typically executed. The getLogger() function accepts a single argument - the logger's name. It returns a reference to a logger instance with the specified name if provided, or root if not. Multiple calls to getLogger() with the same name will return a reference to the same logger object.

How do I create a multiple logging level in Python?

You can set a different logging level for each logging handler but it seems you will have to set the logger's level to the "lowest". In the example below I set the logger to DEBUG, the stream handler to INFO and the TimedRotatingFileHandler to DEBUG. So the file has DEBUG entries and the stream outputs only INFO.

How do you log error messages in Python?

Logging an exception in python with an error can be done in the logging. exception() method. This function logs a message with level ERROR on this logger. The arguments are interpreted as for debug().


1 Answers

This can be done without any additional dependency using a custom LoggerAdapter:

import logging

class LoggerAdapter(logging.LoggerAdapter):
    def __init__(self, prefix, logger):
        super(LoggerAdapter, self).__init__(logger, {})
        self.prefix = prefix

    def process(self, msg, kwargs):
        return '[%s] %s' % (self.prefix, msg), kwargs

class Client:
    def __init__(self, name):
        logger = logging.getLogger(self.__class__.__name__) 
        self.logger = LoggerAdapter(name, logger)
        self.name = name

    def foo(self):
        self.logger.warning('foo: %s', 'bar')

client = Client('client1')
logging.basicConfig(format='%(message)s')
client.foo()

Which should print

[client1] foo: bar
like image 155
Vinay Sajip Avatar answered Sep 28 '22 06:09

Vinay Sajip