Python 中消失的记录器处理程序
Disappearing handlers of logger in Python
我在为多处理进程使用日志记录时遇到了问题。据我了解,所有进程都是独立的,因此每个进程都有自己的记录器。我尝试做的是在主要功能中设置一个记录器,当我启动进程时,将其传递给具有相同配置的所有进程(因此它们记录到同一个文件)。我的问题是,即使它们通过了,处理程序也是空的。这是为什么?
我找到了一个解决方法(将配置参数作为字符串列表传递并在进程开始时重新设置它们)但我想知道是什么导致了这种行为。
我使用的代码:
from multiprocessing import Process, current_process
import logging
def a(x, logger_normal):
logger_normal.debug(f'{current_process().name} - Value of x is {x}')
if __name__ == '__main__':
logger_normal = logging.getLogger('test')
logger_normal.setLevel(logging.DEBUG)
fh_formatter = logging.Formatter('%(asctime)-15s - %(levelname)s - %(lineno)d - %(message)s')
f_handler_normal = logging.FileHandler('normal_debug_log.log')
logger_normal.addHandler(f_handler_normal)
logger_normal.debug('test log main')
p1 = Process(target=a, args=(1, logger_normal))
p2 = Process(target=a, args=(2, logger_normal))
p1.start()
p2.start()
p1.join()
p2.join()
这只会将 'test log main' 写入文件。
这是解决方法的代码:
from multiprocessing import Process
import logging
def a(x, logger_normal, logger_config):
logger_normal.setLevel(logger_config[0])
fh_formatter = logging.Formatter(logger_config[1])
f_handler_normal = logging.FileHandler(logger_config[2])
f_handler_normal.setFormatter(fh_formatter)
logger_normal.addHandler(f_handler_normal)
logger_normal.debug(f'{multiprocessing.current_process().name} - Value of x is {x}')
if __name__ == '__main__':
logger_config = [logging.DEBUG, '%(asctime)-15s - %(levelname)s - %(lineno)d - %(message)s',
'normal_debug_log.log']
logger_normal = logging.getLogger('test')
logger_normal.setLevel(logger_config[0])
fh_formatter = logging.Formatter(logger_config[1])
f_handler_normal = logging.FileHandler(logger_config[2])
f_handler_normal.setFormatter(fh_formatter)
logger_normal.addHandler(f_handler_normal)
logger_normal.debug('test log main')
p1 = Process(target=a, args=(1, logger_normal, logger_config))
p2 = Process(target=a, args=(2, logger_normal, logger_config))
p1.start()
p2.start()
p1.join()
p2.join()
Python Windows 上的子进程从头开始重新运行脚本(spawm
方法)除了 if __name__ == '__main__'
[=16= 中的代码]
-> 记录器不被继承
创建的记录器不是可挑选对象,因此不能通过 multiprocessing.Queue
或 multiprocessing.Pipe
发送
-> 没有简单的方法可以在 start-up
将记录器传递给 child-processes
记录模块解决此问题的方法是,当您将其实例作为 Windows 上的 Process
参数传递时,从头开始重新创建记录器。因此,当 child-process 中出现记录器时,您之前在主进程中设置的所有处理程序都不存在。
Logging Some support for logging is available. Note, however, that the
logging package does not use process shared locks so it is possible
(depending on the handler type) for messages from different processes
to get mixed up.
multiprocessing.get_logger() Returns the logger used by
multiprocessing. If necessary, a new one will be created.
When first created the logger has level logging.NOTSET and no default
handler. Messages sent to this logger will not by default propagate to
the root logger.
Note that on Windows child processes will only inherit the level of
the parent process’s logger – any other customization of the logger
will not be inherited.
我在为多处理进程使用日志记录时遇到了问题。据我了解,所有进程都是独立的,因此每个进程都有自己的记录器。我尝试做的是在主要功能中设置一个记录器,当我启动进程时,将其传递给具有相同配置的所有进程(因此它们记录到同一个文件)。我的问题是,即使它们通过了,处理程序也是空的。这是为什么?
我找到了一个解决方法(将配置参数作为字符串列表传递并在进程开始时重新设置它们)但我想知道是什么导致了这种行为。
我使用的代码:
from multiprocessing import Process, current_process
import logging
def a(x, logger_normal):
logger_normal.debug(f'{current_process().name} - Value of x is {x}')
if __name__ == '__main__':
logger_normal = logging.getLogger('test')
logger_normal.setLevel(logging.DEBUG)
fh_formatter = logging.Formatter('%(asctime)-15s - %(levelname)s - %(lineno)d - %(message)s')
f_handler_normal = logging.FileHandler('normal_debug_log.log')
logger_normal.addHandler(f_handler_normal)
logger_normal.debug('test log main')
p1 = Process(target=a, args=(1, logger_normal))
p2 = Process(target=a, args=(2, logger_normal))
p1.start()
p2.start()
p1.join()
p2.join()
这只会将 'test log main' 写入文件。
这是解决方法的代码:
from multiprocessing import Process
import logging
def a(x, logger_normal, logger_config):
logger_normal.setLevel(logger_config[0])
fh_formatter = logging.Formatter(logger_config[1])
f_handler_normal = logging.FileHandler(logger_config[2])
f_handler_normal.setFormatter(fh_formatter)
logger_normal.addHandler(f_handler_normal)
logger_normal.debug(f'{multiprocessing.current_process().name} - Value of x is {x}')
if __name__ == '__main__':
logger_config = [logging.DEBUG, '%(asctime)-15s - %(levelname)s - %(lineno)d - %(message)s',
'normal_debug_log.log']
logger_normal = logging.getLogger('test')
logger_normal.setLevel(logger_config[0])
fh_formatter = logging.Formatter(logger_config[1])
f_handler_normal = logging.FileHandler(logger_config[2])
f_handler_normal.setFormatter(fh_formatter)
logger_normal.addHandler(f_handler_normal)
logger_normal.debug('test log main')
p1 = Process(target=a, args=(1, logger_normal, logger_config))
p2 = Process(target=a, args=(2, logger_normal, logger_config))
p1.start()
p2.start()
p1.join()
p2.join()
Python Windows 上的子进程从头开始重新运行脚本(
spawm
方法)除了if __name__ == '__main__'
[=16= 中的代码]-> 记录器不被继承
创建的记录器不是可挑选对象,因此不能通过
发送multiprocessing.Queue
或multiprocessing.Pipe
-> 没有简单的方法可以在 start-up
将记录器传递给 child-processes
记录模块解决此问题的方法是,当您将其实例作为 Windows 上的 Process
参数传递时,从头开始重新创建记录器。因此,当 child-process 中出现记录器时,您之前在主进程中设置的所有处理程序都不存在。
Logging Some support for logging is available. Note, however, that the logging package does not use process shared locks so it is possible (depending on the handler type) for messages from different processes to get mixed up.
multiprocessing.get_logger() Returns the logger used by multiprocessing. If necessary, a new one will be created.
When first created the logger has level logging.NOTSET and no default handler. Messages sent to this logger will not by default propagate to the root logger.
Note that on Windows child processes will only inherit the level of the parent process’s logger – any other customization of the logger will not be inherited.