为每个应用实例分离日志记录器名称
我的Python应用程序由主程序和几个模块组成。每个模块在全局范围内包含
import logging
log = logging.getLogger('myapp.mymodule')
的内容。处理程序和其他东西在主程序中初始化,通常所有的消息都会转发到系统日志。
现在我想启动多个应用程序实例(可以通过命令行参数指定配置文件和实例名称)。我的问题是:如何将实例名称传递给每个导入的模块?我希望日志记录器的名称看起来像是'myappinstance.mymodule'或者'myapp.instance.module'。而且我不想在每个模块中处理配置文件解析,因为这会需要硬编码的配置路径。
3 个回答
0
你可以自己写一个日志记录的包装器,这样就能得到正确的名称(根据需要调整,以获取你想要的实例名称):
def get_logger(obj=None):
if isinstance(obj, str):
return logging.getLogger(obj)
elif obj is not None:
logger_name ="%s.%s" % (obj.__class__.__module__, obj.__class__.__name__)
return logging.getLogger(logger_name)
else:
return logging.getLogger()
class Foo(object):
def __init__(self):
self._log = get_logger(self)
或者,如果你觉得进程ID足够用了,那就直接在你的格式化器里使用它:
http://www.python.org/doc/2.5.4/lib/node421.html
formatter = logging.Formatter("%(process)d - %(asctime)s - %(levelname)s - %(message)s")
显然,这样可以唯一标识每个进程,但不会提供与实例相关的信息。
2
我想到一个解决办法:
在主程序中,设置一个叫 myapp
的日志记录器格式。
import logging
logger = logging.getLogger("myapp")
formatter = logging.Formatter("%(asctime)s - instance_name - %(levelname)s - %(message)s")
ch = logging.SysLogHandler()
ch.setFormatter(formatter)
logger.addHandler(ch)
这样,所有使用 myapp.*
的导入模块在日志信息中都会包含实例名称。
0
嗯,描述问题真的有助于解决它 :) 我刚想到一个主意,就是使用环境变量来在所有模块之间传递参数:
main.py:
import os
os.environ['instance'] = 'blah'
import a
a.py:
import os
import b
print 'a:', os.environ['instance']
b.py:
import os
print 'b:', os.environ['instance']
$ python main.py
b: blah
a: blah
还有其他的想法或者批评意见吗?