| import logging |
| import logging.handlers |
| import multiprocessing |
| import multiprocessing.pool |
| |
| from random import choice, random |
| import time |
| |
| |
| class ProcessLogger(multiprocessing.Process): |
| _global_process_logger = None |
| |
| def __init__(self): |
| super().__init__() |
| self.queue = multiprocessing.Queue(-1) |
| |
| @classmethod |
| def get_global_logger(cls): |
| if cls._global_process_logger is not None: |
| return cls._global_process_logger |
| raise Exception("No global process logger exists.") |
| |
| @classmethod |
| def create_global_logger(cls): |
| cls._global_process_logger = ProcessLogger() |
| return cls._global_process_logger |
| |
| @staticmethod |
| def configure(): |
| root = logging.getLogger() |
| h = logging.handlers.RotatingFileHandler('mptest.log', 'a', 300, 10) |
| |
| f = logging.Formatter('%(asctime)s %(processName)-10s %(name)s %(levelname)-8s %(message)s') |
| h.setFormatter(f) |
| root.addHandler(h) |
| |
| def stop(self): |
| self.queue.put_nowait(None) |
| |
| def run(self): |
| self.configure() |
| while True: |
| try: |
| record = self.queue.get() |
| if record is None: |
| break |
| logger = logging.getLogger(record.name) |
| logger.handle(record) |
| |
| except Exception: |
| import sys, traceback |
| print('Whoops! Problem:', file=sys.stderr) |
| traceback.print_exc(file=sys.stderr) |
| |
| def new_process(self, target, args=[], kwargs={}): |
| return ProcessWithLogging(self, target, args, kwargs) |
| |
| |
| def configure_new_process(log_process_queue): |
| h = logging.handlers.QueueHandler(log_process_queue) |
| root = logging.getLogger() |
| root.addHandler(h) |
| root.setLevel(logging.DEBUG) |
| |
| |
| class ProcessWithLogging(multiprocessing.Process): |
| def __init__(self, target, args=[], kwargs={}, log_process=None): |
| super().__init__() |
| self.target = target |
| self.args = args |
| self.kwargs = kwargs |
| if log_process is None: |
| log_process = ProcessLogger.get_global_logger() |
| self.log_process_queue = log_process.queue |
| |
| def run(self): |
| configure_new_process(self.log_process_queue) |
| self.target(*self.args, **self.kwargs) |
| |
| |
| class PoolWithLogging(multiprocessing.pool.Pool): |
| def __init__(self, processes=None, context=None, log_process=None): |
| if log_process is None: |
| log_process = ProcessLogger.get_global_logger() |
| super().__init__(processes=processes, initializer=configure_new_process, |
| initargs=(log_process.queue,), context=context) |
| |
| |
| LEVELS = [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL] |
| LOGGERS = ['a.b.c', 'd.e.f'] |
| MESSAGES = [ |
| 'Random message #1', |
| 'Random message #2', |
| 'Random message #3', |
| ] |
| |
| |
| def worker_process(param=None): |
| name = multiprocessing.current_process().name |
| print('Worker started: %s' % name) |
| time.sleep(random()) |
| logger = logging.getLogger(choice(LOGGERS)) |
| level = choice(LEVELS) |
| message = choice(MESSAGES) |
| logger.log(level, message) |
| print('Worker finished: {}, param: {}'.format(name, param)) |
| return param |
| |
| |
| def main(): |
| |
| process_logger = ProcessLogger.create_global_logger() |
| process_logger.start() |
| |
| |
| workers = [] |
| for i in range(5): |
| worker = ProcessWithLogging(worker_process) |
| workers.append(worker) |
| worker.start() |
| for w in workers: |
| w.join() |
| |
| with PoolWithLogging(processes=4) as pool: |
| print(pool.map(worker_process, range(8))) |
| |
| |
| process_logger.stop() |
| process_logger.join() |
| |
| |
| if __name__ == '__main__': |
| main() |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能