2010-05-17 103 views
5

在我的Python程序结束时,我希望能够获得通过标准logging模块记录的项目数的摘要。我特别希望能够为每个指定名称(以及可能的子项)计数。例如。如果我有:Python日志摘要计数

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") 

然后最后我想获得一个总结,如:

input: 5 
input.network: 2 
output: 1 

我想,通过调用一个记录器或处理程序getcount()方法。

什么是实现这个目标的好方法?我想它会涉及到logging模块中的一个类的子类,但我不确定最好的方法是什么。

回答

3

使用装饰可能是很优雅,我没有测试过这一点,但这样的事情可以工作:

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) 

我意识到,你不希望呼叫的号码登录到每个方法但呼叫每个不同的记录器。尽管如此,我认为装饰者可以非常优雅。

我不认为我已经有足够的睡眠,这个想法将打包调用您的记录器,我混合使用装饰模式与装饰。 (实际上,混合模式和语法将是一个很好的答案)

这是一个更完整的解决方案。对不起,我意识到我是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) 
+0

1对于包括例如!!! – 2010-05-17 07:51:53

2

我认为装饰者模式可能是最干净的方法来实现这一点。

您将传递Logger的一个实例到LoggerDecorator中,该LoggerDecorator将具有与记录器相同的接口。当其中一个方法被调用时,根据需要增加一个成员变量。然后实现getCount()方法将是微不足道的。

这里是在Python实施装饰的引用:

http://wiki.python.org/moin/DecoratorPattern