At the end of my Python program, I'd like to be able to get a summary of the number of items logged through the standard logging
module. I'd specifically like to be able to get a count for each specified name (and possibly its children). E.g. if I have:
input_logger = getLogger('input')
input_logger.debug("got input1")
input_logger.debug("got input2")
input_logger.debug("got input3")
network_input_logger = getLogger('input.network')
network_input_logger.debug("got network input1")
network_input_logger.debug("got network input2")
getLogger('output')
output_logger.debug("sent output1")
Then at the end I'd like to get a summary such as:
input: 5
input.network: 2
output: 1
I'm thinking, by calling a getcount()
method for a logger or a handler.
What would be a good way to achieve this? I imagine it would involve a sub-class of one of the classes in the logging
module, but I'm not sure what would be the best way to go.
The StreamHandler class, located in the core logging package, sends logging output to streams such as sys. stdout, sys. stderr or any file-like object (or, more precisely, any object which supports write() and flush() methods).
Log messages can have 5 levels - DEBUG, INGO, WARNING, ERROR and CRITICAL. They can also include traceback information for exceptions.
Using a decorator could be pretty elegant, I haven't tested this but something like this could work:
class myDecorator(object):
def __init__(self, inner):
self.inner = inner
self.log = {}
def __getattr__(self,name):
self.log[name] = self.log.get(name,0)+1
return getattr(self.inner,name)
def __setattr__(self,name,value):
setattr(self.inner,name,value)
I am realizing that you didn't want to log the number of calls to each method but calls to each different logger. All the same I think a decorator could be pretty elegant.
I don't think I've had enough sleep, the idea would be to wrap calls to your logger, I am mixing the use of a decorator with the decorator pattern. (Actually a mix of the pattern and the syntax would be a great answer)
Here is a more complete solution. I'm sorry I realized I was the someone that was wrong on the internet.
class LoggerLogger(object):
def __init__(self,inner,name):
self.inner = inner
self.calls = 0
def __call__(self,*args,**kwargs):
self.calls += 1
return self.inner(*args,**kwargs)
def loggerDecorator(func):
def inner(name):
logger = func(name)
logger.debug = LoggerLogger(logger.debug,name)
return inner
getLogger = loggerDecorator(getLogger)
I think the decorator pattern might be the cleanest method to implement this.
You will pass an instance of Logger into the LoggerDecorator which will have the same interface as the logger. When one of the methods are called then increment a member variable as appropriate. Then implementing the getCount() method will be trivial.
Here is a reference on implementing decorator in Python:
http://wiki.python.org/moin/DecoratorPattern
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