Python の multiprocessing.Pool
でロギングするコード例を書きました。
1 つのファイルにログをまとめて記録する Python コード例です。
multiprocessing.Pool
で並列処理しているときに、logging
でログを記録する方法です。
説明
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)
manager = multiprocessing.Manager()
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('もちろん、ハンドラを追加すれば、再び記録されます。')
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
で実行しました。
実行結果の画面表示です。
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)>]
もちろん、ハンドラを追加すれば、再び記録されます。
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
で実行しました。
実行結果の画面表示です。
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 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-3 root INFO app_main.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 __mp_main__ DEBUG app_main.py jisaku_func(): デバッグログ 100 あいうえお
SpawnPoolWorker-3 root INFO app_main.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-2 __mp_main__ INFO app_main.py jisaku_func(): インフォログ 100 あいうえお
SpawnPoolWorker-3 root INFO app_main.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-3 root INFO app_main.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-2 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 100 あいうえお
SpawnPoolWorker-3 __mp_main__ DEBUG app_main.py jisaku_func(): デバッグログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-3 __mp_main__ INFO app_main.py jisaku_func(): インフォログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ DEBUG app_main.py jisaku_func(): デバッグログ 300 さしすせそ
SpawnPoolWorker-3 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ INFO app_main.py jisaku_func(): インフォログ 300 さしすせそ
SpawnPoolWorker-3 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-3 __mp_main__ DEBUG 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-3 __mp_main__ INFO app_main.py jisaku_func(): インフォログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-3 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-3 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 500 なにぬねの
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 400 たちつてと
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)>]
もちろん、ハンドラを追加すれば、再び記録されます。
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-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-3 root INFO app_main.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 __mp_main__ DEBUG app_main.py jisaku_func(): デバッグログ 100 あいうえお
SpawnPoolWorker-3 root INFO app_main.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-2 __mp_main__ INFO app_main.py jisaku_func(): インフォログ 100 あいうえお
SpawnPoolWorker-3 root INFO app_main.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 100 あいうえお
SpawnPoolWorker-3 root INFO app_main.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-2 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 100 あいうえお
SpawnPoolWorker-3 __mp_main__ DEBUG app_main.py jisaku_func(): デバッグログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 100 あいうえお
SpawnPoolWorker-3 __mp_main__ INFO app_main.py jisaku_func(): インフォログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ DEBUG app_main.py jisaku_func(): デバッグログ 300 さしすせそ
SpawnPoolWorker-3 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ INFO app_main.py jisaku_func(): インフォログ 300 さしすせそ
SpawnPoolWorker-3 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 200 かきくけこ
SpawnPoolWorker-2 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 300 さしすせそ
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-3 __mp_main__ DEBUG 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-3 __mp_main__ INFO app_main.py jisaku_func(): インフォログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-3 __mp_main__ WARNING app_main.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-3 __mp_main__ ERROR app_main.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-2 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 500 なにぬねの
SpawnPoolWorker-3 __mp_main__ CRITICAL app_main.py jisaku_func(): クリティカルログ 400 たちつてと
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)
manager = multiprocessing.Manager()
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('もちろん、ハンドラを追加すれば、再び記録されます。')
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
で実行しました。
実行結果の画面表示です。
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)>]
もちろん、ハンドラを追加すれば、再び記録されます。
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
で実行しました。
実行結果の画面表示です。
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-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-3 root INFO jisaku.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 jisaku DEBUG jisaku.py jisaku_func(): デバッグログ 300 さしすせそ
SpawnPoolWorker-3 root INFO jisaku.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-2 jisaku INFO jisaku.py jisaku_func(): インフォログ 300 さしすせそ
SpawnPoolWorker-3 root INFO jisaku.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 jisaku WARNING jisaku.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-3 root INFO jisaku.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-2 jisaku ERROR jisaku.py jisaku_func(): エラーログ 300 さしすせそ
SpawnPoolWorker-2 jisaku CRITICAL jisaku.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-3 jisaku DEBUG jisaku.py jisaku_func(): デバッグログ 400 たちつてと
SpawnPoolWorker-2 jisaku DEBUG jisaku.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-3 jisaku INFO jisaku.py jisaku_func(): インフォログ 400 たちつてと
SpawnPoolWorker-2 jisaku INFO jisaku.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 jisaku WARNING jisaku.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-3 jisaku WARNING jisaku.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 jisaku ERROR jisaku.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-3 jisaku ERROR jisaku.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-2 jisaku CRITICAL jisaku.py jisaku_func(): クリティカルログ 500 なにぬねの
SpawnPoolWorker-3 jisaku CRITICAL jisaku.py jisaku_func(): クリティカルログ 400 たちつてと
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)>]
もちろん、ハンドラを追加すれば、再び記録されます。
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-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-3 root INFO jisaku.py jisaku_initializer(): (キューハンドラ追加完了)
SpawnPoolWorker-2 jisaku DEBUG jisaku.py jisaku_func(): デバッグログ 300 さしすせそ
SpawnPoolWorker-3 root INFO jisaku.py jisaku_initializer(): root.level: DEBUG (10)
SpawnPoolWorker-2 jisaku INFO jisaku.py jisaku_func(): インフォログ 300 さしすせそ
SpawnPoolWorker-3 root INFO jisaku.py jisaku_initializer(): logger.level: NOTSET (0)
SpawnPoolWorker-2 jisaku WARNING jisaku.py jisaku_func(): ウォーニングログ 300 さしすせそ
SpawnPoolWorker-3 root INFO jisaku.py jisaku_initializer(): qh.level: NOTSET (0)
SpawnPoolWorker-2 jisaku ERROR jisaku.py jisaku_func(): エラーログ 300 さしすせそ
SpawnPoolWorker-2 jisaku CRITICAL jisaku.py jisaku_func(): クリティカルログ 300 さしすせそ
SpawnPoolWorker-3 jisaku DEBUG jisaku.py jisaku_func(): デバッグログ 400 たちつてと
SpawnPoolWorker-2 jisaku DEBUG jisaku.py jisaku_func(): デバッグログ 500 なにぬねの
SpawnPoolWorker-3 jisaku INFO jisaku.py jisaku_func(): インフォログ 400 たちつてと
SpawnPoolWorker-2 jisaku INFO jisaku.py jisaku_func(): インフォログ 500 なにぬねの
SpawnPoolWorker-2 jisaku WARNING jisaku.py jisaku_func(): ウォーニングログ 500 なにぬねの
SpawnPoolWorker-3 jisaku WARNING jisaku.py jisaku_func(): ウォーニングログ 400 たちつてと
SpawnPoolWorker-2 jisaku ERROR jisaku.py jisaku_func(): エラーログ 500 なにぬねの
SpawnPoolWorker-3 jisaku ERROR jisaku.py jisaku_func(): エラーログ 400 たちつてと
SpawnPoolWorker-2 jisaku CRITICAL jisaku.py jisaku_func(): クリティカルログ 500 なにぬねの
SpawnPoolWorker-3 jisaku CRITICAL jisaku.py jisaku_func(): クリティカルログ 400 たちつてと
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
でログを記録するコード例。
- multiprocessing.Pool でログを記録するコード例(プロセスごとに分ける)
- multiprocessing.Pool でログを記録するコード例(まとめて記録)
普通のシングルプロセスでログを記録するコード例。
- ロガーでロギングするコード例【logging】
- ルートロガーでログを記録するコード例【logging】
- ログファイルを『ファイルサイズでローテーション』するコード例
- ログファイルを『時間でローテーション』するコード例
- logging.NullHandler() の使い方
- logging フォーマットの出力例(10種類以上)
- 例外を自作して使うコード例(ユーザー定義例外)
並列処理のコード例。
以上です。