python - 为什么在进程启动后添加 python 日志处理程序时不使用?

标签 python python-3.x logging

如果我正确解释了 python3 文档,无论我将处理程序添加到根记录器的何处,来自进程内的日志消息都应该发送到文件。然而,事实并非如此。

这是一个演示该问题的完整程序:

import logging
import logging.handlers

from multiprocessing import Process
from time import sleep

fileHandler = logging.FileHandler( 'mylog.log' )
fileHandler.setLevel( 5 )

logger = logging.getLogger( None )

def process_logger():

    print( "process waiting" )
    sleep( 5 )
    print( 'process start' )

    logger = logging.getLogger( None )

    for num in range( 1, 10 ):
        logger.critical( "critical: %d" % num )
        sleep(1)

#
# if this is where the handler is added, the critical messages
# will go to the file
#
logger.addHandler( fileHandler )

processLogger = Process( target=process_logger )
processLogger.start()

#
# if this is where the handler is added, the critical messages
# will not go to the file.
#
#logger.addHandler( fileHandler )

print( "started" )

我在 OS X 10.10.4 上使用 python 3.4.3。

我对为什么这不起作用的猜测是,当我启动进程时,它会复制当前环境,如果当时尚未添加处理程序,则进程运行的环境将不会拥有它。

我有三个问题:

  1. 为什么无论我在哪里调用 logger.addHandler,我的消息并不总是最终出现在文件中?

  2. 我的消息应该始终保存在文件中吗?

  3. 如果不应该,那么对于在进程启动后需要操作处理程序的一般问题的最佳解决方案是什么?

最佳答案

您看到的行为是由于进程在 POSIX 上的工作方式造成的。 POSIX 上的多处理通常使用 fork 系统调用,当您通过 Process(...) 调用创建另一个进程时会发生这种情况。此时,创建的进程是原始进程的副本。当您在 Process(...) 调用之前添加处理程序时,副本中也已添加了处理程序,因此 process_logger (即在副本中调用)将按预期运行。当您在 Process(...) 调用之后添加处理程序时,该处理程序尚未添加到副本中,因此 process_logger (在副本中调用)将行为不符合预期。

为了避免此类问题,请确保在每个进程中根据需要配置日志记录(通常,这意味着在从 调用(直接或间接)的代码中进行日志记录配置) >target=XXX 可调用,传递给 Process。在您的情况下,这是 process_logger

更新:请参阅 this post了解有关将日志记录多处理结合使用的更多信息。

关于python - 为什么在进程启动后添加 python 日志处理程序时不使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31621818/

相关文章:

python - OS X 安装 Sphinx : The 'sphinx-build' and 'sphinx-quickstart' not found

python - 写入列中包含多个列表项的 csv 行

python - Scrapy Python Craigslist 爬虫

python - 属性错误 : module '' has no attribute '__path__'

java - 记录每个 jsp :include

reactjs - 在哪里调用Sentry.configureScope?

javascript - 使用 JavaScript 进行 Python RQ 排队

python-3.x - 尝试拆分对象数据类型的列以在数据帧中创建单独的列。收到错误 : "' float object is not subscriptable"

python - 在 Cygwin 上安装 Pip-3.2

linux - 在 Linux 中 : Print last line of log file that starts with