【Python】multiprocessing.Pool でログを記録するコード例(まとめて記録)

Python

Python の multiprocessing.Pool でロギングするコード例を書きました。

1 つのファイルにログをまとめて記録する Python コード例です。

multiprocessing.Pool で並列処理(マルチプロセス処理)しているときに、logging でログを記録する方法です。

環境は Windows 10 Pro (64 bit) で、Python 3.10.4 (64 bit) を使用しました。

説明

QueueListenerキューリスナーQueueHandlerキューハンドラ を使用して、ログを記録します。

「ログの画面表示」と「ログファイルへの書き込み」は、全部 QueueListener のスレッドにおまかせします。

おやプロセスとかくプロセスのロガーには、QueueHandler だけを取り付けます。

QueueListener のスレッドがログを受信して、QueueListener のスレッドだけが、画面やファイルに書き込みます。

これで、ログを 1 つのファイルにまとめることができました。

【Python】logging でログを記録する方法のドキュメントの場所(コメント付き)

メインモジュールをロギングする

メインモジュールを multiprocessing.Pool で並列実行するときのコード例です。

コード例

メインモジュールのコードです。

app_main.py

import logging, logging.handlers, pathlib
import multiprocessing
logger = logging.getLogger(__name__) # NOTSET (0)
# 親プロセスの名前付きロガー または 各子プロセスの名前付きロガー

def main():
    """メイン関数です。"""
    root = logging.getLogger() # 親プロセスのルートロガー
    root.setLevel(logging.INFO) # WARNING (30) ⇒ INFO (20)

    with multiprocessing.Manager() as manager:
        print(f'(manager._process) {manager._process}')
        que = manager.Queue(-1)
        # type(manager): <class 'multiprocessing.managers.SyncManager'>
        # type(que): <class 'multiprocessing.managers.AutoProxy[Queue]'>

        qh = logging.handlers.QueueHandler(que) # NOTSET (0)
        root.addHandler(qh)

        sh = logging.StreamHandler() # NOTSET (0)
        sh.setFormatter(logging.Formatter( # %()-17s: 17 文字分のスペースで左寄せ。
            '%(processName)-17s %(name)-11s %(levelname)-8s '
            '%(module)s.py %(funcName)s(): %(message)s'))

        log_txt = pathlib.Path(rf'F:\apps\log\mp-qh-{__name__}.txt')
        fh = logging.FileHandler(log_txt, encoding='utf-8', mode='a') # NOTSET (0)
        fh.setFormatter(logging.Formatter(
            '%(processName)-17s %(name)-11s %(levelname)-8s '
            '%(module)s.py %(funcName)s(): %(message)s'))

        listener = logging.handlers.QueueListener(que, sh, fh, respect_handler_level=True)
        listener.start() # type(listener): <class 'logging.handlers.QueueListener'>
        try:
            root.info('(QueueListener) start')
            root.info(f'root.level: {logging.getLevelName(root.level)} ({root.level})')
            root.info(f'logger.level: {logging.getLevelName(logger.level)} ({logger.level})')
            root.info(f'qh.level: {logging.getLevelName(qh.level)} ({qh.level})')
            root.info(f'sh.level: {logging.getLevelName(sh.level)} ({sh.level})')
            root.info(f'fh.level: {logging.getLevelName(fh.level)} ({fh.level})')

            logger.debug('デバッグログ') # 今は出ません root: INFO (20)
            logger.info('インフォログ')
            logger.warning('ウォーニングログ')
            logger.error('エラーログ')
            logger.critical('クリティカルログ')

            logger.info('pool.map() を実行します。')
            max_processes = 1
            logger.info(f'プロセス数 max_processes: {max_processes}')
            args_list = [
                [100, 'あいうえお'],
                [200, 'かきくけこ'],
                [300, 'さしすせそ'],
                [400, 'たちつてと'],
                [500, 'なにぬねの'],
            ]
            with multiprocessing.Pool(
                    processes=max_processes,
                    initializer=jisaku_initializer, initargs=(que,),
                ) as pool: # type(pool): <class 'multiprocessing.pool.Pool'>
                datas = pool.map(jisaku_func_wrapper, args_list)

            logger.info('pool.map() の結果を表示します。')
            for data in datas:
                logger.info(data)
            root.info('(QueueListener) end')
        finally:
            listener.stop()

        print('QueueListener を止めたので、以降はロガーを使用しても記録されません。')
        print(root.handlers)
        logger.critical('クリティカルログ')
        root.critical('クリティカルログ')
    print(f'(manager._process) {manager._process}')

    print('もちろん、ハンドラを追加すれば、再び記録されます。')
    root.removeHandler(qh)
    root.addHandler(sh)
    root.addHandler(fh)
    root.info(f'\n{root.handlers}')
    logger.critical('クリティカルログ')
    root.critical('クリティカルログ')
    return

def jisaku_initializer(que):
    """各子プロセスで最初に 1 回だけ実行される関数です。"""
    root = logging.getLogger() # 各子プロセスのルートロガー
    root.setLevel(logging.DEBUG) # WARNING (30) ⇒ DEBUG (10)
    qh = logging.handlers.QueueHandler(que) # NOTSET (0)
    root.addHandler(qh)
    root.info('(キューハンドラ追加完了)')
    root.info(f'root.level: {logging.getLevelName(root.level)} ({root.level})')
    root.info(f'logger.level: {logging.getLevelName(logger.level)} ({logger.level})')
    root.info(f'qh.level: {logging.getLevelName(qh.level)} ({qh.level})')
    return

def jisaku_func_wrapper(args):
    return jisaku_func(*args)

def jisaku_func(number, text):
    """自作関数です。"""
    logger.debug(f'デバッグログ {number} {text}')
    logger.info(f'インフォログ {number} {text}')
    logger.warning(f'ウォーニングログ {number} {text}')
    logger.error(f'エラーログ {number} {text}')
    logger.critical(f'クリティカルログ {number} {text}')
    return [number, text, 'OK']

if __name__ == '__main__':
    main()

実行結果 (processes=1)

メインモジュールprocesses=1 で実行しました。

実行結果の画面表示です。

(manager._process) <SpawnProcess name='SyncManager-1' pid=13752 parent=4632 started>
MainProcess       root        INFO     app_main.py main(): (QueueListener) start   
MainProcess       root        INFO     app_main.py main(): root.level: INFO (20)   
MainProcess       root        INFO     app_main.py main(): logger.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): qh.level: NOTSET (0)    
MainProcess       root        INFO     app_main.py main(): sh.level: NOTSET (0)    
MainProcess       root        INFO     app_main.py main(): fh.level: NOTSET (0)    
MainProcess       __main__    INFO     app_main.py main(): インフォログ
MainProcess       __main__    WARNING  app_main.py main(): ウォーニングログ        
MainProcess       __main__    ERROR    app_main.py main(): エラーログ
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ        
MainProcess       __main__    INFO     app_main.py main(): pool.map() を実行します。  
MainProcess       __main__    INFO     app_main.py main(): プロセス数 max_processes: 1
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): root.level: DEBUG (10)  
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): qh.level: NOTSET (0)    
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 100 あいうえお    
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 100 あいうえお    
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 100 あいうえお      
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 200 かきくけこ    
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 200 かきくけこ    
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 200 かきくけこ      
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 300 さしすせそ    
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 300 さしすせそ    
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 300 さしすせそ      
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 400 たちつてと    
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 400 たちつてと    
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 400 たちつてと      
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 400 たちつてと        
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 500 なにぬねの        
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 500 なにぬねの        
MainProcess       __main__    INFO     app_main.py main(): pool.map() の結果を表示します。
MainProcess       __main__    INFO     app_main.py main(): [100, 'あいうえお', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [200, 'かきくけこ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [300, 'さしすせそ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [400, 'たちつてと', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [500, 'なにぬねの', 'OK']
MainProcess       root        INFO     app_main.py main(): (QueueListener) end
QueueListener を止めたので、以降はロガーを使用しても記録されません。
[<QueueHandler (NOTSET)>]
(manager._process) <SpawnProcess name='SyncManager-1' pid=13752 parent=4632 stopped exitcode=0>
もちろん、ハンドラを追加すれば、再び記録されます。
MainProcess       root        INFO     app_main.py main():
[<StreamHandler <stderr> (NOTSET)>, <FileHandler F:\apps\log\mp-qh-__main__.txt (NOTSET)>]
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       root        CRITICAL app_main.py main(): クリティカルログ

ログファイルの内容です。

mp-qh-__main__.txt

MainProcess       root        INFO     app_main.py main(): (QueueListener) start
MainProcess       root        INFO     app_main.py main(): root.level: INFO (20)
MainProcess       root        INFO     app_main.py main(): logger.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): qh.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): sh.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): fh.level: NOTSET (0)
MainProcess       __main__    INFO     app_main.py main(): インフォログ
MainProcess       __main__    WARNING  app_main.py main(): ウォーニングログ
MainProcess       __main__    ERROR    app_main.py main(): エラーログ
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       __main__    INFO     app_main.py main(): pool.map() を実行します。
MainProcess       __main__    INFO     app_main.py main(): プロセス数 max_processes: 1
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 500 なにぬねの
MainProcess       __main__    INFO     app_main.py main(): pool.map() の結果を表示します。
MainProcess       __main__    INFO     app_main.py main(): [100, 'あいうえお', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [200, 'かきくけこ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [300, 'さしすせそ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [400, 'たちつてと', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [500, 'なにぬねの', 'OK']
MainProcess       root        INFO     app_main.py main(): (QueueListener) end
MainProcess       root        INFO     app_main.py main(): 
[<StreamHandler <stderr> (NOTSET)>, <FileHandler F:\apps\log\mp-qh-__main__.txt (NOTSET)>]
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       root        CRITICAL app_main.py main(): クリティカルログ

実行結果 (processes=2)

メインモジュールprocesses=2 で実行しました。

実行結果の画面表示です。

(manager._process) <SpawnProcess name='SyncManager-1' pid=4500 parent=10280 started>
MainProcess       root        INFO     app_main.py main(): (QueueListener) start      
MainProcess       root        INFO     app_main.py main(): root.level: INFO (20)      
MainProcess       root        INFO     app_main.py main(): logger.level: NOTSET (0)   
MainProcess       root        INFO     app_main.py main(): qh.level: NOTSET (0)       
MainProcess       root        INFO     app_main.py main(): sh.level: NOTSET (0)       
MainProcess       root        INFO     app_main.py main(): fh.level: NOTSET (0)       
MainProcess       __main__    INFO     app_main.py main(): インフォログ
MainProcess       __main__    WARNING  app_main.py main(): ウォーニングログ
MainProcess       __main__    ERROR    app_main.py main(): エラーログ
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       __main__    INFO     app_main.py main(): pool.map() を実行します。  
MainProcess       __main__    INFO     app_main.py main(): プロセス数 max_processes: 2
SpawnPoolWorker-3 root        INFO     app_main.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-3 root        INFO     app_main.py jisaku_initializer(): root.level: DEBUG (10)  
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-3 root        INFO     app_main.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): root.level: DEBUG (10)  
SpawnPoolWorker-3 root        INFO     app_main.py jisaku_initializer(): qh.level: NOTSET (0)    
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-3 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 100 あいうえお    
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): qh.level: NOTSET (0)    
SpawnPoolWorker-3 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 100 あいうえお    
SpawnPoolWorker-3 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 200 かきくけこ    
SpawnPoolWorker-3 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 100 あいうえお      
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 200 かきくけこ    
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-3 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 300 さしすせそ    
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 200 かきくけこ      
SpawnPoolWorker-3 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 300 さしすせそ    
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-3 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 400 たちつてと    
SpawnPoolWorker-3 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 300 さしすせそ      
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 400 たちつてと
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 300 さしすせそ        
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 400 たちつてと        
SpawnPoolWorker-3 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-3 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 400 たちつてと        
SpawnPoolWorker-3 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 500 なにぬねの        
SpawnPoolWorker-3 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 500 なにぬねの        
MainProcess       __main__    INFO     app_main.py main(): pool.map() の結果を表示します。
MainProcess       __main__    INFO     app_main.py main(): [100, 'あいうえお', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [200, 'かきくけこ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [300, 'さしすせそ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [400, 'たちつてと', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [500, 'なにぬねの', 'OK']
MainProcess       root        INFO     app_main.py main(): (QueueListener) end
QueueListener を止めたので、以降はロガーを使用しても記録されません。
[<QueueHandler (NOTSET)>]
(manager._process) <SpawnProcess name='SyncManager-1' pid=4500 parent=10280 stopped exitcode=0>
もちろん、ハンドラを追加すれば、再び記録されます。
MainProcess       root        INFO     app_main.py main():
[<StreamHandler <stderr> (NOTSET)>, <FileHandler F:\apps\log\mp-qh-__main__.txt (NOTSET)>]
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       root        CRITICAL app_main.py main(): クリティカルログ

ログファイルの内容です。

mp-qh-__main__.txt

MainProcess       root        INFO     app_main.py main(): (QueueListener) start
MainProcess       root        INFO     app_main.py main(): root.level: INFO (20)
MainProcess       root        INFO     app_main.py main(): logger.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): qh.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): sh.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): fh.level: NOTSET (0)
MainProcess       __main__    INFO     app_main.py main(): インフォログ
MainProcess       __main__    WARNING  app_main.py main(): ウォーニングログ
MainProcess       __main__    ERROR    app_main.py main(): エラーログ
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       __main__    INFO     app_main.py main(): pool.map() を実行します。
MainProcess       __main__    INFO     app_main.py main(): プロセス数 max_processes: 2
SpawnPoolWorker-3 root        INFO     app_main.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-3 root        INFO     app_main.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-3 root        INFO     app_main.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-3 root        INFO     app_main.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-3 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 100 あいうえお
SpawnPoolWorker-2 root        INFO     app_main.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-3 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 100 あいうえお
SpawnPoolWorker-3 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 200 かきくけこ
SpawnPoolWorker-3 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 200 かきくけこ
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-3 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 200 かきくけこ
SpawnPoolWorker-3 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-3 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 400 たちつてと
SpawnPoolWorker-3 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 400 たちつてと
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-3 __mp_main__ DEBUG    app_main.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-3 __mp_main__ INFO     app_main.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 400 たちつてと
SpawnPoolWorker-3 __mp_main__ WARNING  app_main.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-3 __mp_main__ ERROR    app_main.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 500 なにぬねの
MainProcess       __main__    INFO     app_main.py main(): pool.map() の結果を表示します。
MainProcess       __main__    INFO     app_main.py main(): [100, 'あいうえお', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [200, 'かきくけこ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [300, 'さしすせそ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [400, 'たちつてと', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [500, 'なにぬねの', 'OK']
MainProcess       root        INFO     app_main.py main(): (QueueListener) end
MainProcess       root        INFO     app_main.py main(): 
[<StreamHandler <stderr> (NOTSET)>, <FileHandler F:\apps\log\mp-qh-__main__.txt (NOTSET)>]
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       root        CRITICAL app_main.py main(): クリティカルログ

自作ライブラリをロギングする

自作ライブラリを multiprocessing.Pool で並列実行するときのコード例です。

コード例

メインモジュールのコードです。

app_main.py

import logging, logging.handlers, pathlib
import multiprocessing
import jisaku
logger = logging.getLogger(__name__) # NOTSET (0)
# 親プロセスの名前付きロガー

def main():
    """メイン関数です。"""
    root = logging.getLogger() # 親プロセスのルートロガー
    root.setLevel(logging.INFO) # WARNING (30) ⇒ INFO (20)

    with multiprocessing.Manager() as manager:
        print(f'(manager._process) {manager._process}')
        que = manager.Queue(-1)
        # type(manager): <class 'multiprocessing.managers.SyncManager'>
        # type(que): <class 'multiprocessing.managers.AutoProxy[Queue]'>

        qh = logging.handlers.QueueHandler(que) # NOTSET (0)
        root.addHandler(qh)

        sh = logging.StreamHandler() # NOTSET (0)
        sh.setFormatter(logging.Formatter( # %()-17s: 17 文字分のスペースで左寄せ。
            '%(processName)-17s %(name)-11s %(levelname)-8s '
            '%(module)s.py %(funcName)s(): %(message)s'))

        log_txt = pathlib.Path(rf'F:\apps\log\mp-qh-lib-{__name__}.txt')
        fh = logging.FileHandler(log_txt, encoding='utf-8', mode='a') # NOTSET (0)
        fh.setFormatter(logging.Formatter(
            '%(processName)-17s %(name)-11s %(levelname)-8s '
            '%(module)s.py %(funcName)s(): %(message)s'))

        listener = logging.handlers.QueueListener(que, sh, fh, respect_handler_level=True)
        listener.start() # type(listener): <class 'logging.handlers.QueueListener'>
        try:
            root.info('(QueueListener) start')
            root.info(f'root.level: {logging.getLevelName(root.level)} ({root.level})')
            root.info(f'logger.level: {logging.getLevelName(logger.level)} ({logger.level})')
            root.info(f'qh.level: {logging.getLevelName(qh.level)} ({qh.level})')
            root.info(f'sh.level: {logging.getLevelName(sh.level)} ({sh.level})')
            root.info(f'fh.level: {logging.getLevelName(fh.level)} ({fh.level})')

            logger.debug('デバッグログ') # 今は出ません root: INFO (20)
            logger.info('インフォログ')
            logger.warning('ウォーニングログ')
            logger.error('エラーログ')
            logger.critical('クリティカルログ')

            logger.info('pool.map() を実行します。')
            max_processes = 1
            logger.info(f'プロセス数 max_processes: {max_processes}')
            args_list = [
                [100, 'あいうえお'],
                [200, 'かきくけこ'],
                [300, 'さしすせそ'],
                [400, 'たちつてと'],
                [500, 'なにぬねの'],
            ]
            with multiprocessing.Pool(
                    processes=max_processes,
                    initializer=jisaku.jisaku_initializer, initargs=(que,),
                ) as pool: # type(pool): <class 'multiprocessing.pool.Pool'>
                datas = pool.map(jisaku.jisaku_func_wrapper, args_list)

            logger.info('pool.map() の結果を表示します。')
            for data in datas:
                logger.info(data)
            root.info('(QueueListener) end')
        finally:
            listener.stop()

        print('QueueListener を止めたので、以降はロガーを使用しても記録されません。')
        print(root.handlers)
        logger.critical('クリティカルログ')
        root.critical('クリティカルログ')
    print(f'(manager._process) {manager._process}')

    print('もちろん、ハンドラを追加すれば、再び記録されます。')
    root.removeHandler(qh)
    root.addHandler(sh)
    root.addHandler(fh)
    root.info(f'\n{root.handlers}')
    logger.critical('クリティカルログ')
    root.critical('クリティカルログ')
    return

if __name__ == '__main__':
    main()

自作ライブラリのコードです。

jisaku.py

import logging, logging.handlers
logger = logging.getLogger(__name__) # NOTSET (0)
# 親プロセスの名前付きロガー または 各子プロセスの名前付きロガー

def jisaku_initializer(que):
    """各子プロセスで最初に 1 回だけ実行される関数です。"""
    root = logging.getLogger() # 各子プロセスのルートロガー
    root.setLevel(logging.DEBUG) # WARNING (30) ⇒ DEBUG (10)
    qh = logging.handlers.QueueHandler(que) # NOTSET (0)
    root.addHandler(qh)
    root.info('(キューハンドラ追加完了)')
    root.info(f'root.level: {logging.getLevelName(root.level)} ({root.level})')
    root.info(f'logger.level: {logging.getLevelName(logger.level)} ({logger.level})')
    root.info(f'qh.level: {logging.getLevelName(qh.level)} ({qh.level})')
    return

def jisaku_func_wrapper(args):
    return jisaku_func(*args)

def jisaku_func(number, text):
    """自作関数です。"""
    logger.debug(f'デバッグログ {number} {text}')
    logger.info(f'インフォログ {number} {text}')
    logger.warning(f'ウォーニングログ {number} {text}')
    logger.error(f'エラーログ {number} {text}')
    logger.critical(f'クリティカルログ {number} {text}')
    return [number, text, 'OK']

実行結果 (processes=1)

自作ライブラリprocesses=1 で実行しました。

実行結果の画面表示です。

(manager._process) <SpawnProcess name='SyncManager-1' pid=2456 parent=14088 started>
MainProcess       root        INFO     app_main.py main(): (QueueListener) start   
MainProcess       root        INFO     app_main.py main(): root.level: INFO (20)   
MainProcess       root        INFO     app_main.py main(): logger.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): qh.level: NOTSET (0)    
MainProcess       root        INFO     app_main.py main(): sh.level: NOTSET (0)    
MainProcess       root        INFO     app_main.py main(): fh.level: NOTSET (0)    
MainProcess       __main__    INFO     app_main.py main(): インフォログ
MainProcess       __main__    WARNING  app_main.py main(): ウォーニングログ
MainProcess       __main__    ERROR    app_main.py main(): エラーログ
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       __main__    INFO     app_main.py main(): pool.map() を実行します。  
MainProcess       __main__    INFO     app_main.py main(): プロセス数 max_processes: 1
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): root.level: DEBUG (10)  
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): qh.level: NOTSET (0)    
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 100 あいうえお    
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 100 あいうえお    
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 100 あいうえお      
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 200 かきくけこ    
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 200 かきくけこ    
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 200 かきくけこ      
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 300 さしすせそ    
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 300 さしすせそ    
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 300 さしすせそ      
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 400 たちつてと    
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 400 たちつてと    
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 400 たちつてと      
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 400 たちつてと
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 500 なにぬねの
MainProcess       __main__    INFO     app_main.py main(): pool.map() の結果を表示します。
MainProcess       __main__    INFO     app_main.py main(): [100, 'あいうえお', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [200, 'かきくけこ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [300, 'さしすせそ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [400, 'たちつてと', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [500, 'なにぬねの', 'OK']
MainProcess       root        INFO     app_main.py main(): (QueueListener) end
QueueListener を止めたので、以降はロガーを使用しても記録されません。
[<QueueHandler (NOTSET)>]
(manager._process) <SpawnProcess name='SyncManager-1' pid=2456 parent=14088 stopped exitcode=0>
もちろん、ハンドラを追加すれば、再び記録されます。
MainProcess       root        INFO     app_main.py main():
[<StreamHandler <stderr> (NOTSET)>, <FileHandler F:\apps\log\mp-qh-lib-__main__.txt (NOTSET)>]
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       root        CRITICAL app_main.py main(): クリティカルログ

ログファイルの内容です。

mp-qh-lib-__main__.txt

MainProcess       root        INFO     app_main.py main(): (QueueListener) start
MainProcess       root        INFO     app_main.py main(): root.level: INFO (20)
MainProcess       root        INFO     app_main.py main(): logger.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): qh.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): sh.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): fh.level: NOTSET (0)
MainProcess       __main__    INFO     app_main.py main(): インフォログ
MainProcess       __main__    WARNING  app_main.py main(): ウォーニングログ
MainProcess       __main__    ERROR    app_main.py main(): エラーログ
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       __main__    INFO     app_main.py main(): pool.map() を実行します。
MainProcess       __main__    INFO     app_main.py main(): プロセス数 max_processes: 1
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 100 あいうえお
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 100 あいうえお
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 100 あいうえお
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 300 さしすせそ
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 300 さしすせそ
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 300 さしすせそ
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 400 たちつてと
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 400 たちつてと
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 400 たちつてと
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 500 なにぬねの
MainProcess       __main__    INFO     app_main.py main(): pool.map() の結果を表示します。
MainProcess       __main__    INFO     app_main.py main(): [100, 'あいうえお', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [200, 'かきくけこ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [300, 'さしすせそ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [400, 'たちつてと', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [500, 'なにぬねの', 'OK']
MainProcess       root        INFO     app_main.py main(): (QueueListener) end
MainProcess       root        INFO     app_main.py main(): 
[<StreamHandler <stderr> (NOTSET)>, <FileHandler F:\apps\log\mp-qh-lib-__main__.txt (NOTSET)>]
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       root        CRITICAL app_main.py main(): クリティカルログ

実行結果 (processes=2)

自作ライブラリprocesses=2 で実行しました。

実行結果の画面表示です。

(manager._process) <SpawnProcess name='SyncManager-1' pid=13588 parent=14704 started>
MainProcess       root        INFO     app_main.py main(): (QueueListener) start    
MainProcess       root        INFO     app_main.py main(): root.level: INFO (20)    
MainProcess       root        INFO     app_main.py main(): logger.level: NOTSET (0) 
MainProcess       root        INFO     app_main.py main(): qh.level: NOTSET (0)     
MainProcess       root        INFO     app_main.py main(): sh.level: NOTSET (0)     
MainProcess       root        INFO     app_main.py main(): fh.level: NOTSET (0)     
MainProcess       __main__    INFO     app_main.py main(): インフォログ
MainProcess       __main__    WARNING  app_main.py main(): ウォーニングログ
MainProcess       __main__    ERROR    app_main.py main(): エラーログ
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       __main__    INFO     app_main.py main(): pool.map() を実行します。
MainProcess       __main__    INFO     app_main.py main(): プロセス数 max_processes: 2
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-3 root        INFO     jisaku.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): root.level: DEBUG (10)  
SpawnPoolWorker-3 root        INFO     jisaku.py jisaku_initializer(): root.level: DEBUG (10)  
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-3 root        INFO     jisaku.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): qh.level: NOTSET (0)    
SpawnPoolWorker-3 root        INFO     jisaku.py jisaku_initializer(): qh.level: NOTSET (0)    
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 100 あいうえお    
SpawnPoolWorker-3 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 200 かきくけこ    
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 100 あいうえお    
SpawnPoolWorker-3 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 200 かきくけこ    
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-3 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 100 あいうえお      
SpawnPoolWorker-3 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 200 かきくけこ      
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-3 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 300 さしすせそ    
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 300 さしすせそ    
SpawnPoolWorker-3 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 400 たちつてと    
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-3 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 400 たちつてと    
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 300 さしすせそ
SpawnPoolWorker-3 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-3 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-3 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 400 たちつてと
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 500 なにぬねの
MainProcess       __main__    INFO     app_main.py main(): pool.map() の結果を表示します。
MainProcess       __main__    INFO     app_main.py main(): [100, 'あいうえお', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [200, 'かきくけこ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [300, 'さしすせそ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [400, 'たちつてと', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [500, 'なにぬねの', 'OK']
MainProcess       root        INFO     app_main.py main(): (QueueListener) end
QueueListener を止めたので、以降はロガーを使用しても記録されません。
[<QueueHandler (NOTSET)>]
(manager._process) <SpawnProcess name='SyncManager-1' pid=13588 parent=14704 stopped exitcode=0>
もちろん、ハンドラを追加すれば、再び記録されます。
MainProcess       root        INFO     app_main.py main():
[<StreamHandler <stderr> (NOTSET)>, <FileHandler F:\apps\log\mp-qh-lib-__main__.txt (NOTSET)>]
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       root        CRITICAL app_main.py main(): クリティカルログ

ログファイルの内容です。

mp-qh-lib-__main__.txt

MainProcess       root        INFO     app_main.py main(): (QueueListener) start
MainProcess       root        INFO     app_main.py main(): root.level: INFO (20)
MainProcess       root        INFO     app_main.py main(): logger.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): qh.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): sh.level: NOTSET (0)
MainProcess       root        INFO     app_main.py main(): fh.level: NOTSET (0)
MainProcess       __main__    INFO     app_main.py main(): インフォログ
MainProcess       __main__    WARNING  app_main.py main(): ウォーニングログ
MainProcess       __main__    ERROR    app_main.py main(): エラーログ
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       __main__    INFO     app_main.py main(): pool.map() を実行します。
MainProcess       __main__    INFO     app_main.py main(): プロセス数 max_processes: 2
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-3 root        INFO     jisaku.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-3 root        INFO     jisaku.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-3 root        INFO     jisaku.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 root        INFO     jisaku.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-3 root        INFO     jisaku.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 100 あいうえお
SpawnPoolWorker-3 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 100 あいうえお
SpawnPoolWorker-3 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-3 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 100 あいうえお
SpawnPoolWorker-3 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-3 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 300 さしすせそ
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 300 さしすせそ
SpawnPoolWorker-3 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 400 たちつてと
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-3 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 400 たちつてと
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 300 さしすせそ
SpawnPoolWorker-3 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-3 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-2 jisaku      DEBUG    jisaku.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-3 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 400 たちつてと
SpawnPoolWorker-2 jisaku      INFO     jisaku.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      WARNING  jisaku.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      ERROR    jisaku.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-2 jisaku      CRITICAL jisaku.py jisaku_func(): クリティカルログ 500 なにぬねの
MainProcess       __main__    INFO     app_main.py main(): pool.map() の結果を表示します。
MainProcess       __main__    INFO     app_main.py main(): [100, 'あいうえお', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [200, 'かきくけこ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [300, 'さしすせそ', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [400, 'たちつてと', 'OK']
MainProcess       __main__    INFO     app_main.py main(): [500, 'なにぬねの', 'OK']
MainProcess       root        INFO     app_main.py main(): (QueueListener) end
MainProcess       root        INFO     app_main.py main(): 
[<StreamHandler <stderr> (NOTSET)>, <FileHandler F:\apps\log\mp-qh-lib-__main__.txt (NOTSET)>]
MainProcess       __main__    CRITICAL app_main.py main(): クリティカルログ
MainProcess       root        CRITICAL app_main.py main(): クリティカルログ

関連記事

concurrent.futures でログを記録するコード例。

multiprocessing でログを記録するコード例。

普通のシングルプロセスでログを記録するコード例。

並列処理のコード例。

以上です。

スポンサーリンク
シェアする(押すとSNS投稿用の『編集ページ』に移動します)
フォローする(RSSフィードに移動します)
スポンサーリンク
シラベルノート
タイトルとURLをコピーしました