
Python+Qtアプリ開発日記#5
今回の記事は、loggerの追加だけどその前に、VSCODEでデバック中の状態をまず確認。確認するのはまずカレントディレクトリは?この状態でどこになっている?ということでmain.pyのmainモジュールに確認のコードをこんな感じで追加。※osとsysモジュールを使うことになるのでimportをつける。

ターミナルにprintでos.getcwd()で取得したカレントを表示すると、ソース・ファイルと違うディレクトリになっているのがわかる。
どうやらVSCODEのワークスペースを保存したところになるようだ。
ちょっとこのままだと良くないので、"launch.json"ファイルを更新。
"launch.json"には、実行時のカレントディレクトリをどこにするのかを決定する、"cwd"がある。(このあたりは自動で設定してほしいな)
これを、ワークスペースがあるところから"main.py"があるディレクトリし示すように設定を追加する。

この状態で再度、デバック実行。

期待通り、カレントディレクトリが"main.py"があるところになった。
ちなみに、実行時のPythonインタプリタの指定が.VENVで作成した仮想環境になっているのを確認しておくこと。VSCODEの右下で以下のように".VENV"になっていれば期待通り。もし違っている場合は、コマンドパレットを開いて、Pythonインタプリター選択で".VENV"を選択すること。

さらに"sys.path"も確認してみる。sys.pathはリストなのでpprintを使って表示してみる。

ちゃんと"main.py"が格納されているディレクトリが追加されている。※一安心。
さて、いよいよlogger(ログ)を設定するモジュールを作る。
できたコードがこちら。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import os
from logging import Formatter, StreamHandler
from logging.handlers import RotatingFileHandler
def my_logging_setup(
log_path: str,
log_file: str,
log_size: int | str,
log_backup_count: int | str,
) -> None:
"""ロギング設定を初期化する関数。
Args:
log_path (str): ログファイルを保存するディレクトリのパス。
log_file (str): ログファイルの名前。
log_size (int | str): ログファイルの最大サイズ(MB単位)。整数または文字列で指定。
log_backup_count (int | str): ログファイルのバックアップの数。整数または文字列で指定。
Returns:
None
"""
formatter = Formatter(
"%(asctime)s : %(levelname)s : %(filename)s - %(message)s"
)
stream_handler = StreamHandler()
stream_handler.setLevel(logging.INFO)
stream_handler.setFormatter(formatter)
log_fname = os.path.join(log_path, log_file)
size = int(log_size) if isinstance(log_size, (int, str)) else 100
size *= 1024 * 1024
backup_count = (
int(log_backup_count)
if isinstance(log_backup_count, (int, str))
else 4
)
file_handler = RotatingFileHandler(
log_fname,
maxBytes=size,
backupCount=backup_count,
encoding="utf-8",
)
logging.basicConfig(
level=logging.NOTSET, handlers=[stream_handler, file_handler]
)
モジュール名は、”my_logging_setup”という名前を付けた。
やっていることはdocstringの通りで簡単に解説するとStreamHandler(ストリームハンドラ)クラスとRotatingFileHandler(ローテーティングファイルハンドラ)を使って。引数で指定されたファイルパスにファイル名で指定した名前でログファイルを作成。ログファイルは指定サイズ(100MByte)に達するとバックアップされそれは4回までとしている。
内容は、色々なところで公開されているオーソドックスな内容です。
多少、工夫したのはサイズ、回数は文字列または整数どちらでも指定できるようにしたぐらい。※文字列を受けられるようにしたのは、別の理由から。
これを、mainモジュールで使った例は以下の通り。

ターミナルにログも出力されるが、出力したログはファイル化されているはずなのでそちらを確認する。
確認すると期待通り出力されているのがわかる。

次回は、いよいよGUIを作っていく回にしようと思います。