Python 每个应用程序实例的单独记录器名称
我的python应用程序由主程序和几个模块组成。每个模块包含Python 每个应用程序实例的单独记录器名称,python,logging,Python,Logging,我的python应用程序由主程序和几个模块组成。每个模块包含 import logging log = logging.getLogger('myapp.mymodule') 在全球一级。处理程序和其他在主程序中初始化的东西,以及通常转发到syslog的所有消息 现在我想启动应用程序的多个实例(可以将实例名为的配置文件指定为命令行参数)。问题是:如何将实例名称传递给每个导入的模块?我希望记录器名称看起来像“myappinstance.mymodule”或“myapp.instance.modu
import logging
log = logging.getLogger('myapp.mymodule')
在全球一级。处理程序和其他在主程序中初始化的东西,以及通常转发到syslog的所有消息
现在我想启动应用程序的多个实例(可以将实例名为的配置文件指定为命令行参数)。问题是:如何将实例名称传递给每个导入的模块?我希望记录器名称看起来像“myappinstance.mymodule”或“myapp.instance.module”。我不想在每个模块中对配置文件进行解析,因为这需要硬编码的配置路径。我可以想到一个解决方案: 在主程序中,设置名为
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)
然后,使用logger
myapp.
导入的所有模块都将在日志消息中包含实例名称。描述问题确实有助于解决此问题:)刚想到使用环境变量在所有模块之间传递参数:
main.py:
import os
os.environ['instance'] = 'blah'
import a
a、 py:
b、 py:
$python main.py
b: blah
a: blah
对此还有其他想法或批评吗?只需编写自己的日志包装器,它将为您提供正确的名称(根据需要进行调整,以获得所需的实例名): 或者,如果进程id对您来说足够好,只需在格式化程序中使用它:
显然,这将唯一地标识每个流程,但不会给您任何与实例相关的信息。我认为这不会解决您的问题。通过设置环境变量将实例名称传递给模块是有条件的。如果多个实例同时启动怎么办?环境变量不是全局的(操作系统范围),它们是沿着进程树继承的。我可以同时启动两个main.py实例,如果每个实例都设置特定的evnironment变量,则它将仅传播到子进程。
import os
print 'b:', os.environ['instance']
b: blah
a: blah
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)
formatter = logging.Formatter("%(process)d - %(asctime)s - %(levelname)s - %(message)s")