Pythonでログ処理をやってみた
Pythonでログ処理をやってみた
コード全文
とりあえず、作成したコード全文
# utf-8
import os
import sys
from CONST import *
def set_log() -> None:
"""
ログの設定
* 標準ログとエラーログの2種類を設定している
:return: None
"""
if not os.path.exists(LOG_PATH): # ログフォルダがなかったら作成
os.mkdir(LOG_PATH)
info_handler = logging.FileHandler(filename=LOG_FILENAME % 'STAND', encoding=UTF8, mode='a')
info_handler.setLevel(logging.INFO)
info_handler.setFormatter(logging.Formatter(LOG_FORMAT))
info_handler.addFilter(lambda record: record.levelno <= logging.INFO)
error_handler = logging.FileHandler(filename=LOG_FILENAME % 'ERROR', encoding=UTF8, mode='a')
error_handler.setLevel(logging.ERROR)
error_handler.setFormatter(logging.Formatter(LOG_FORMAT))
stream_handler = logging.StreamHandler(sys.stderr)
stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
stream_handler.setLevel(logging.ERROR)
info_log.addHandler(info_handler)
error_log.addHandler(error_handler)
error_log.addHandler(stream_handler)
コードの説明
コード内の関数 set_log()
は、プログラム内で使用される2種類のログ(標準ログとエラーログ)の設定を行っています。以下でその詳細を説明します。
-
ログフォルダの作成:
if not os.path.exists(LOG_PATH): os.mkdir(LOG_PATH)
ログフォルダが存在しない場合、新たにログフォルダを作成します。このフォルダはログファイルを保存するための場所です。
-
標準ログとエラーログの設定:
info_handler = logging.FileHandler(filename=LOG_FILENAME % 'STAND', encoding=UTF8, mode='a') info_handler.setLevel(logging.INFO) # ... (以下略) error_handler = logging.FileHandler(filename=LOG_FILENAME % 'ERROR', encoding=UTF8, mode='a') error_handler.setLevel(logging.ERROR) # ... (以下略)
info_handler
は、標準ログを記録するための設定です。error_handler
は、エラーログを記録するための設定です。それぞれのハンドラでは、ログファイルのパスやファイル名、エンコーディング、出力モードを指定しています。また、ログのレベルをフィルタリングして、特定のレベルのログのみを記録します。 -
エラーレベルのログをコンソールにも出力:
stream_handler = logging.StreamHandler(sys.stderr) stream_handler.setFormatter(logging.Formatter(LOG_FORMAT)) stream_handler.setLevel(logging.ERROR)
stream_handler
は、エラーレベルのログを標準エラーストリーム(通常はコンソール)にも出力するための設定です。これにより、エラーが発生した際にログファイルだけでなく、コンソールにもエラーメッセージが表示されます。 -
ハンドラをロガーに追加:
info_log.addHandler(info_handler) error_log.addHandler(error_handler) error_log.addHandler(stream_handler)
設定したハンドラをそれぞれのロガーに追加しています。これにより、ログの記録がハンドラによって行われるようになります。
これをつくった経緯
このコードは、プログラムが実行される際に、重要な情報やエラーなどの出力を記録するためのものです。例えば、プログラムが動作中に何が起こっているかを確認したい場合や、プログラムがエラーで停止した際に原因を調査したい場合に役立ちます。
コード内では、ログの設定が行われています。標準ログとエラーログの2種類のログがあり、それぞれのログには異なる情報が記録されます。さらに、エラーのレベルに応じてログの内容をフィルタリングして表示します。また、エラーが発生した場合には、エラーメッセージがコンソールにも表示されるようになっています。
ログはプログラム開発やトラブルシューティングの際に非常に役立つツールであり、このコードによってログを効果的に処理する仕組みが構築されています。
追加・修正すべきポイント
適当につくったので、以下の内容を追加・修正するともっとよくなるかも
-
ロギングレベルの設定: ログの重要度に応じて適切なレベルを設定しましょう。開発中はDEBUGレベル、運用中はINFOレベル以上が一般的です。以下のように設定します。
info_handler.setLevel(logging.DEBUG) # または logging.INFO error_handler.setLevel(logging.ERROR) stream_handler.setLevel(logging.ERROR)
-
ログのフォーマット: ログの表示形式をカスタマイズすることができます。例えば、日時やログレベル、メッセージなどを含める場合はフォーマット文字列を設定します。
LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s' info_handler.setFormatter(logging.Formatter(LOG_FORMAT)) error_handler.setFormatter(logging.Formatter(LOG_FORMAT)) stream_handler.setFormatter(logging.Formatter(LOG_FORMAT))
-
ログローテーション: ログファイルが肥大化するのを防ぐために、ログローテーション(古いログを自動的に削除・圧縮する)を設定することがおすすめです。
RotatingFileHandler
やTimedRotatingFileHandler
を使用して実現できます。 -
ログのコンソール表示: 現在の設定ではエラーレベルのログがコンソールにも表示されますが、全てのログレベルをコンソールに表示するか、一部のレベルだけ表示するかを選択できるようにすることも考慮できます。
-
エラーログの詳細情報: エラーログにはスタックトレースなどの詳細情報を含めると、エラーの原因特定が容易になります。これにより、問題のある箇所を特定しやすくなります。
-
ログの場所の柔軟性: ログフォルダのパスやファイル名は、コード内で直接ハードコードされています。将来的な変更を容易にするために、設定ファイルなどを使ってログファイルの場所を管理することを検討できます。
-
複数ハンドラの統合: 現在の設定では標準ログとエラーログに異なるハンドラを使用していますが、共通の設定やフォーマットを使いまわすこともできます。
これらのアイデアを元に、より柔軟で効果的なログ処理を実現するためにコードをカスタマイズしてみてください。
Discussion