0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python, logging での loop 処理、注意事項と実運用

Last updated at Posted at 2025-04-16

log 難しかった (∩´﹏`∩)

基本

main.py
import logging
import os

from my_modules import my_func1, my_func2


if __name__ == '__main__':
    save_dir = '/mnt/c/Users/me/repo/my_repo'

    logging.basicConfig(level=logging.DEBUG,
                        format="%(asctime)s %(levelname)s %(name)s %(message)s",
                        datefmt="[%X]",
                        handlers=[logging.FileHandler(filename=os.path.join(save_dir, "log.txt"), mode="w")])

    logger = logging.getLogger(__name__)
    logger.debug("aaa")
    logger.info("bbb")

    my_func1()
    my_func2()
my_modules
from logging import getLogger


logger = getLogger("__main__").getChild("my_modules")

def my_func1():
    logger.info("ccc")

def my_func2():
    logger.info("ddd")

loop 毎に別の log.txt 作りたい

前提: basicConfig() は1回しか使っちゃダメ

loop_log_example.py
import logging
import os

save_dir = '/mnt/c/Users/me/repo/my_repo'
os.makedirs(save_dir, exist_ok=True)

# basicConfig で全体のフォーマット・レベル設定
# 絶対1回だけ!loop 内に書かないで!
logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s %(levelname)s %(message)s",
    datefmt="[%X]",
    )

logger = logging.getLogger("my_logger")

for i in range(3):
    log_path = os.path.join(save_dir, f"log_{i}.txt")
    handler = logging.FileHandler(log_path, mode="w")
    formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s", datefmt="[%X]")
    handler.setFormatter(formatter)
    logger.addHandler(handler)
    logger.info(f"{i}回目のログ!")
    logger.removeHandler(handler)
    handler.close()    # 忘れずにクローズしておく

とか

今回作ったやーつ

Archtecture

  • my_repo
    • config
      • config.yaml
    • src
      • __init__.py
      • main.py
        • modules
          • __init__.py
          • config.py (config 読むためのファイル (内容は割愛))
          • my_function.py

各ファイルの具体的な内容

config.yaml
modes:
    mode1:
        input_dir: /mnt/c/Users/my_name/my_repo/dataset/original/mode1
        save_dir: /mnt/c/Users/my_name/my_repo/dataset/preprocess/mode1
    mode2:
        input_dir: /mnt/c/Users/my_name/my_repo/dataset/original/mode2
        save_dir: /mnt/c/Users/my_name/my_repo/dataset/preprocess/mode2
main.py
import argparse
import logging
import os

from modules import func


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='')
    parser.add_argument('--config', dest='config_path',
                        action='store', required=True,
                        help='path to the config.yaml')
    args = parser.parse_args()

    config_path = args.config_path

    config = load_config(config_path)

    modes = config['modes']

    logging.basicConfig(level=logging.DEBUG,
                        format="%(asctime)s %(levelname)s %(name)s %(message)s",
                        datefmt="[%X]"
                        )

    for mode in modes:
        input_dir = modes[mode]['input_dir']
        save_dir = modes[mode]['save_dir']

        os.makedirs(save_dir, exist_ok=True)

        logger = logging.getLogger(__name__)
        logger.setLevel(logging.DEBUG)
        if logger.hasHandlers():    # もし古い handler が残っていたら
            logger.handlers.clear()    # 削除する
        handler = logging.FileHandler(filename=os.path.join(save_dir, "log.txt"), mode="w")
        handler.setLevel(logging.DEBUG)
        formatter = logging.Formatter("%(asctime)s %(levelname)s %(name)s %(message)s", datefmt="[%X]")
        handler.setFormatter(formatter)
        logger.addHandler(handler)

        logger.info(f"mode: {mode}")

        input_files = sorted(glob.glob(os.path.join(input_dir, "*.mp4")))
        logger.info(f"num files: {len(input_files)}")

        for input_file in input_files:
            res = func(input_file, save_dir)
            logger.info(f"{res}")    # 文字列化

        handler.close()    # loop 毎に handler 閉じる
modules/__init__.py
from .my_function import func
modules/my_function.py
from logging import getLogger


logger = getLogger("__main__").getChild("my_func")

def func(input_file, save_dir):
    # do something
    logger.info("何か書くとか")
    logger.info(f"{save_dir} 表示してみたり?")
    return res

実行

python src/main.py --config config/config.yaml

これで、mode1 の save_dir と mode2 の save_dir 内に各々 log.txt が出来ているはずっ!
Yay!

付録

困ったときは、これらの情報を見たら何かのヒントになるかもね!

print("logger name:", logger.name)
print("logger level:", logger.level)
print("logger propagate:", logger.propagate)
print("logger handlers:", logger.handlers)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?