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
-
modules
-
config
各ファイルの具体的な内容
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)