Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 每个应用程序实例的单独记录器名称_Python_Logging - Fatal编程技术网

Python 每个应用程序实例的单独记录器名称

Python 每个应用程序实例的单独记录器名称,python,logging,Python,Logging,我的python应用程序由主程序和几个模块组成。每个模块包含 import logging log = logging.getLogger('myapp.mymodule') 在全球一级。处理程序和其他在主程序中初始化的东西,以及通常转发到syslog的所有消息 现在我想启动应用程序的多个实例(可以将实例名为的配置文件指定为命令行参数)。问题是:如何将实例名称传递给每个导入的模块?我希望记录器名称看起来像“myappinstance.mymodule”或“myapp.instance.modu

我的python应用程序由主程序和几个模块组成。每个模块包含

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")