【发布时间】:2019-04-20 02:09:37
【问题描述】:
我是 Python 的新手,记录多进程对我来说似乎很困惑。目前使用 Python 3.6.6
我创建了一个脚本来设置我的处理程序并允许我创建唯一的日志名称(我想要为每个进程创建)或使用主日志文件。
在控制台中我想显示警告和错误,在日志文件中我想跟踪调试消息。
logging_config.py
import logging
import sys
import os
import pathlib
CONSOLE_FORMATER = logging.Formatter("%(levelname)s - %(message)s")
FILE_FORMATTER = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s.%(funcName)s:%(lineno)d - %(message)s'")
def getConsoleHandler():
consoleHandler = logging.StreamHandler(sys.stdout)
consoleHandler.setFormatter(CONSOLE_FORMATER)
consoleHandler.setLevel(logging.WARNING)
return consoleHandler
def getFileHandler(**kwargs):
path = createLogDir()
if 'logName' in kwargs:
logFile = path + "/" + kwargs['logName'] + ".log"
else:
logFile = path + "/deploy-orchestrator.log"
# fileHandler = logging.FileHandler(logFile, mode='w')
fileHandler = logging.FileHandler(logFile)
fileHandler.setFormatter(FILE_FORMATTER)
fileHandler.setLevel(logging.DEBUG)
return fileHandler
def createLogDir():
path = f"{os.path.dirname(os.getcwd())}/logs" # get working parent dir
pathlib.Path(path).mkdir(exist_ok=True) # create /logs dir, if it exists throw no errors
return path
# if uniqueLog is set to true then a log will be made with the logger name
def getLogger(loggerName, **kwargs):
logger = logging.getLogger(loggerName)
logger.addHandler(getConsoleHandler())
if 'uniqueLog' in kwargs and kwargs['uniqueLog'] is True:
logger.addHandler(getFileHandler(logName=loggerName))
else:
logger.addHandler(getFileHandler())
logger.setLevel(logging.DEBUG)
logger.propagate = False
return logger
对于简单的日志记录,我可以导入我的 logging_config 并记录我需要的任何内容。
simple_example.py
import logging_config as logs
logger = logs.getLogger(__name__)
logger.debug("This works just fine and goes into the default log file")
logger.warning("This works just fine and goes to console and the log file")
现在是什么不起作用。
multiprocess_parent.py
from multiprocessing import Process
processes = []
for child_name in children:
process_child = ProcessChild(child_name)
p = Process(target=process_child.worker, args=(widget))
processes.append(p)
p.start()
for p in processes:
p.join()
multiprocess_child.py
import logging_config as logs
class ProcessChild:
logger = None
def __init__(self, child_name):
self.child_name = child_name
self.logger = logging.getLogger(child_name, uniqueLog=True) # Each child getting it's own log file
def worker(widget):
logger.info("This EXPLODES")
我得到的错误是ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle _thread.RLock objects
它来自p.start()这一行
那么在这种情况下,您如何为每个进程写入单独的日志文件呢?我最初的想法是在这里创建一个错误的logging_config.py 吗?我这样做是为了让多个模块可以使用相同的配置。
另一方面,日志文件本身是用正确的名称正确创建的,当每个进程尝试写入正确的日志文件时,就会发生此错误。
【问题讨论】:
标签: python python-3.x