关于动态python日志记录的想法

时间:2014-03-28 13:54:09

标签: python python-2.7 logging dynamic

我有一个应用程序,它根据外部参数运行几个主应用程序实例。主应用程序导入少量库,而这些库又导入其他库。他们都有全球性的

LOGGER = logging.getLogger('module_name')

将记录器配置为文件处理程序,以便将所有日志写入外部文件(所有日志都写入同一文件)。现在我想根据传递给主应用程序的特定名称将日志写入不同的文件。我需要一些像

这样的东西

LOGGER = logging.getLogger(dynamic_criteria_name)

结果将创建多个日志文件dynamic_criteria_name.log,dynamic_criteria_name.log等,并且任何时间记录器都应根据调用的条件从任何应该写入正确文件的模块中调用。

但问题是LOGGER是全球性的。我可以将记录器或dynamic_criteria_name传递给每个函数来写入日志但是听起来有些错误。可能我只是偏执狂!我有模块,有时只有功能。我想不想把记录器全部传过来。

我考虑过AOP一段时间,但我不认为它真的是交叉切割,因为它是动态生成的,记录器看起来像是横切,但在主应用程序的一个实例中。我已经考虑过其他方法来破解全球状态,但我认为动态性质使得至少在我脑海中这一切都无法实现。

下面是伪代码(我还没试过它运行它)但它更好地解释了我所说的我想的。如您所见,module_1导入module_2和module_3,它们都有一个全局LOGGER,而module_3调用module_4。我想知道是否可以从module_2或module_3写入单独的日志文件,而不会明确地将名称传递给每个导入的模块函数。我可以使用不同的文件名向记录器添加多个处理程序但是如何从另一个模块引用正确的记录器,因为它们目前都是全局的。

# module_1.py
import logging
import time

import module_2
import module_3

LOGGER = logging.getLogger()


def start_main_loop(name):
    while True:
        module_2.say_boo()
        module_3.say_foo()
        LOGGER.debug('Sleeping...')
        time.sleep(10)

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    for i in xrange(10):
        start_main_loop(i)

#----------------------------------------------------        
# module_2.py

import logging

LOGGER = logging.getLogger()

def say_boo():
    msg = 'boo'
    LOGGER.debug(msg)
    LOGGER.debug(say_twice(msg))

def say_twice(msg):
    LOGGER.debug('Called say twice')
    return msg * 2

#----------------------------------------------------    
# module_3.py

import logging

import module_4

LOGGER = logging.getLogger()

def say_foo():
    msg = 'foo'
    LOGGER.debug(msg)
    LOGGER.debug(say_twice(msg))
    module_4.say_bar()

def say_twice(msg):
    LOGGER.debug('Called say twice')
    return msg * 2

#----------------------------------------------------    
# module_4.py

import logging

LOGGER = logging.getLogger()

def say_bar():
    msg = 'bar'
    LOGGER.debug(msg)

我愿意探索人们可能有的任何想法。希望我已经清楚地解释了自己,如果不是请让我知道,我可以重新解释这个问题。谢谢!

1 个答案:

答案 0 :(得分:0)

您不需要传递记录器:记录器是单件。如果多个模块中的代码调用getLogger('foo'),则每次调用都会返回相同的实例。因此无需传递记录器实例。通常,记录器名称指示记录调用的来源,因此__name__值最有意义。您可以将模块foo中的代码记录到名为bar的记录器中 - 没有什么可以阻止您这样做 - 它在实践中并没有被发现特别有用。

听起来像AOP太过分了。您可以考虑向根记录器添加多个处理程序,而不是传递记录器名称,并根据您的特定要求在每个处理程序上使用特定过滤器以确保特定文件位于特定文件中。