我使用Amazon CloudWatch进行日志记录,使用Python中内置的日志记录,并添加了CloudWatch处理程序。我的问题是,当试图为进程设置日志记录时,处理程序并没有添加到docker环境中,但它在本地运行时运行良好。
示例代码:
main.py
import os
from multiprocessing import Process
from logger import logger
from worker import worker
def app():
logger.info({'message': 'Main process started',
'pid': os.getpid()})
p1 = Process(target=worker)
p1.start()
p1.join()
logger.info({'message': 'In main process',
'pid': os.getpid()})
if __name__ == '__main__':
app()
worker.py
import os
def worker():
from logger import logger
logger.info({'message': 'In worker process',
'pid': os.getpid()})
logger.py
import os
import logging
from watchtower import CloudWatchLogHandler
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('foo-logger')
logger.addHandler(CloudWatchLogHandler())
logger.info({'message': 'CloudWatch handler added',
'pid': os.getpid()})
我的预期输出(X是主进程的PID,Y是辅助进程的PID(。这是我在本地运行代码时的输出。
INFO:foo-logger:{"message": "CloudWatch handler added", "pid": X}
INFO:foo-logger:{"message": "Main process started", "pid": X}
INFO:foo-logger:{"message": "CloudWatch handler added", "pid": Y}
INFO:foo-logger:{"message": "In worker process", "pid": Y}
INFO:foo-logger:{"message": "In main process", "pid": X}
实际输出。这是在Docker中运行时的输出。
INFO:foo-logger:{"message": "CloudWatch handler added", "pid": X}
INFO:foo-logger:{"message": "Main process started", "pid": X}
INFO:foo-logger:{"message": "In worker process", "pid": Y} <-- Before this line I want the handler to be added
INFO:foo-logger:{"message": "In main process", "pid": X}
请解释一下我没有想到什么,以及如何在多处理程序中使用日志。
编辑:经过更多的保留,我可以通过设置set_start_method('fork')
在本地复制Docker行为,因为我的Mac似乎使用了派生方法而不是fork…根据文档,fork方法应该更快。
解决方案是设置set_start_method('spawn')
。有关此问题的原因和进一步解释的更多详细信息,请访问以下两个链接:
- https://bugs.python.org/issue6721
- https://pythonspeed.com/articles/python-multiprocessing/