您应该编写消息聚合/统计类而不是尝试挂钩日志系统的单例,但我想您可能有一个使用日志记录的现有代码库.
我还建议你应该实例化你的记录器,而不是总是使用默认的root.在Python记录食谱具有广泛的解释和例子.
以下课程应该按照你的要求做.
import logging import atexit import pprint class Aggregator(object): logs = {} @classmethod def _aggregate(cls, record): id = '{0[levelname]}:{0[name]}:{0[msg]}'.format(record.__dict__) if id not in cls.logs: # first occurrence cls.logs[id] = [1, record] else: # subsequent occurrence cls.logs[id][0] += 1 @classmethod def _output(cls): for count, record in cls.logs.values(): record.__dict__['msg'] += ' (occured {} times)'.format(count) logging.getLogger(record.__dict__['name']).handle(record) @staticmethod def filter(record): # pprint.pprint(record) Aggregator._aggregate(record) return False @staticmethod def exit(): Aggregator._output() logging.getLogger().addFilter(Aggregator) atexit.register(Aggregator.exit) for i in range(99999): try: asdf[i] # not defined! except NameError: logging.exception('foo') # generates large number of logging events else: pass # ... more code with more logging ... for i in range(88888): logging.error('more of the same') # ... and so on ...
请注意,在程序退出之前,您不会获得任何日志.
运行它的结果是:
ERROR:root:foo (occured 99999 times) Traceback (most recent call last): File "C:\work\VEMS\python\logcount.py", line 38, in asdf[i] # not defined! NameError: name 'asdf' is not defined ERROR:root:more of the same (occured 88888 times)