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.
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.
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.
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().
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With