python记录器中的序言和尾声

时间:2014-09-29 08:08:09

标签: python logging

我希望创建一个记录器类,在第一次logging.getLogger()编写序言时,一旦进程结束记录器并写一个结尾

我的代码:

logger = logging.getLogger('name')
logger.info('HI')

预期产出:

2014-09-29 10:50:40,187 - INFO - ** My prologue **
2014-09-29 10:50:40,187 - INFO - HI
2014-09-29 10:50:40,187 - INFO - ** My epilogue **

2 个答案:

答案 0 :(得分:1)

正如所观察到的,我以前的答案中的epiLoggers不是“单身人士”,必须在将要使用它们的模块之间传递。

解决此问题的选项包括

  • 继承logger.Logger(如果这实际上是可行的,我没有调查过),
  • 实现一种机制来创建和存储和检索epiLogger,例如logger.getLogger(荒谬过分夸大的想法)
  • 创建一个可以在多个模块中使用的类似单身的epiLogger。

这个解决方案是后者。

import logging

class epiLogger():
    _initialised = {}
    _finalised = {}

    def __init__(self, name):
        self.logger = logging.getLogger(name)
        self.name = name
        if not epiLogger._initialised.get(name):
            self.logger.addHandler(logging.StreamHandler())
            self.logger.setLevel(logging.INFO)
            self.logger.info('** My Prologue **')
            epiLogger._initialised[self.name] = True

    def info(self, the_info):
        self.logger.info(the_info)

    def __del__(self):
        if not self.__class__._finalised.get(self.name):
            self.logger.info('** My Epilogue **')
            self.__class__._finalised[self.name] = True

a = epiLogger("foo")

a.info("foo!")
a.info("bar!")
a.info("party!")

我知道这样做是件好事,但请在此处阅读:http://jalf.dk/blog/2010/03/singletons-solving-problems-you-didnt-know-you-never-had-since-1995/。我会认真地问自己“实际上,从长远来看,将每个epiLogger传递到它所属的位置可能是最好的吗?”

当然还是investigate subclassing logger.Logger:)

答案 1 :(得分:0)

这是一种蛮力,简单的实施。

请注意,您要在epiLogger上调用的任何logging.Logger方法都需要实现:我只实现了info()。

import logging

# class definition for the new logger that does the pro and epilogues

class epiLogger():
    def __init__(self, name):
        self.logger = logging.getLogger(name)
        self.logger.info('** My Prologue **')

    def info(self, the_info):
        self.logger.info(the_info)

    def __del__(self):
        self.logger.info('** My Epilogue **')

# preamble to set up the underlying logger that it needs
# ... could be inside the class constructor, depending on whether the class
# is supposed to be "encapsulating and providing"  or "using" this external one

the_logger = logging.getLogger("foo")
the_logger.setLevel(logging.INFO)

the_logger.addHandler(logging.StreamHandler())

# using the good stuff...

a = epiLogger("foo")

a.info("foo!")
a.info("bar!")
a.info("party!")

产生

~ mgregory$ python foo.py
** My Prologue **
foo!
bar!
party!
** My Epilogue **
~ mgregory$ 

(为简单起见,我省略了时间/日期格式等,因为它与问题无关)