ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

Python - loggingモジュール:ログ

初めに

 Pythonでは、logging モジュールを使用してログを記録することができます。本記事はloggingモジュールの基本的な使い方をまとめています。

loggingモジュールの基本

 Python では、logging モジュールを使用してログを記録します。このモジュールは、ログメッセージのレベル、出力先、書式などを設定するための機能を提供します。

ログレベル

 ログメッセージには、重要度を示すレベルが設定されます。デフォルトで用意されているレベルは以下のとおりです。

ログレベル 説明
DEBUG デバッグログ
INFO 通常の動作に関する情報のログ
WARNING 潜在的な問題に関する警告のログ
ERROR エラーメッセージログ
CRITICAL 致命的なエラーログ

 通常はWARNING以上のログのみ表示されます。

logger, handler, filter, formatter

 loggingモジュールは次の4つを使い、ログを記録、管理します。

部品 説明
logger ログメッセージの生成と送信を担当するオブジェクト
getLogger(name)関数で名前を指定してロガーを取得する
debug(), info(), warning(), error(), critical()でそれぞれのレベルでログメッセージを記録する
handler ロガーから送信されたログメッセージを受け取り、出力先へ送信するオブジェクト
コンソールに出力する StreamHandler が使用される
filter ロガーから送信されたログメッセージを検査し、出力するかどうかを決定するオブジェクト
formatter ログメッセージを最終的に出力される形式に変換するオブジェクト

ログの記録

 logging モジュールの logger オブジェクトを使用することで、ログを記録することができます。その際、ログレベルの設定ができます。

import logging

logger = logging.getLogger(__name__)

logger.debug("This is a debug message")
logger.info("This is an info message")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")
基本的な例文
from logging import getLogger, StreamHandler, Formatter

# ロガーを取得
logger = getLogger(__name__)

# ハンドラを作成
stream_handler = StreamHandler()

# フォーマッタを作成
formatter = Formatter("%(asctime)s %(levelname)s %(message)s")

# ハンドラにフォーマッタを設定
stream_handler.setFormatter(formatter)

# ロガーにハンドラを追加
logger.addHandler(stream_handler)

# ログメッセージを記録
logger.debug("This is a debug message")
logger.info("This is an info message")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")

(実行結果)

 前述の通り、ログレベルWARNING以上のログのみ出力されます。

詳細の説明

setLebel()

 logger, handlerには, setLebel()関数が用意されています。これによりログメッセージの最低レベルを設定することができます。

コード 説明
logger.setLebel() そのロガーが生成するログメッセージの最低レベルを設定
handler.setLebel() そのハンドラが出力するログメッセージの最低レベルを設定

 先ほど、ログレベルWARNING以上のログのみ出力が出力されると説明しましたが、これはデフォルトの logger.setLebel() が WARNING に設定されているためです。

 実際、先ほどのコードにlogger.setLebel()を DEBUG に変更するコードを追加して実行してみます。

from logging import getLogger, StreamHandler, Formatter, DEBUG

# ロガーを取得
logger = getLogger(__name__)

# ロガーのログレベルを設定
logger.setLevel(DEBUG)

# ハンドラを作成
stream_handler = StreamHandler()

# フォーマッタを作成
formatter = Formatter("%(asctime)s %(levelname)s %(message)s")

# ハンドラにフォーマッタを設定
stream_handler.setFormatter(formatter)

# ロガーにハンドラを追加
logger.addHandler(stream_handler)

# ログメッセージを記録
logger.debug("This is a debug message")
logger.info("This is an info message")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")

(実行結果)

 これにさらにhandler.setLebel()を ERROR に変更するコードを追加して実行してみます。

from logging import getLogger, StreamHandler, Formatter, DEBUG, ERROR

# ロガーを取得
logger = getLogger(__name__)

# ロガーのログレベルを設定
logger.setLevel(DEBUG)

# ハンドラを作成
stream_handler = StreamHandler()

# フォーマッタを作成
formatter = Formatter("%(asctime)s %(levelname)s %(message)s")

# ハンドラにフォーマッタを設定
stream_handler.setFormatter(formatter)

# ハンドラのログレベルを設定
stream_handler.setLevel(ERROR)

# ロガーにハンドラを追加
logger.addHandler(stream_handler)

# ログメッセージを記録
logger.debug("This is a debug message")
logger.info("This is an info message")
logger.warning("This is a warning message")
logger.error("This is an error message")
logger.critical("This is a critical message")

(実行結果)

 ログレベル ERROR 未満のログは生成されていますが、handler で出力されないように設定されているため、上の実行結果になっています。

 ログとして生成、出力されるには、logger, handler のログの最低レベルをどちらも満たしている必要があります。

ハンドラ

 上記では、StreamHandlerを使い、ログ出力をしました。他のハンドラを用い、別の出力先をしていすることができます。

ハンドラ 説明
StreamHandler 標準出力 (sys.stdout) にログメッセージを出力する
デバッグや開発時に使用される
FileHandler 指定されたファイルにログメッセージを出力する
RotatingFileHandler 指定されたファイルにログメッセージを出力する
ファイルサイズが大きくなった場合は、自動的にローテーションされる
ログファイルのサイズを制限したい場合に使用される
TimedRotatingFileHandler 指定されたファイルにログメッセージを出力する
時間間隔で自動的にローテーションされる
ログファイルを定期的にローテーションしたい場合に使用される
SMTPHandler SMTP サーバにログメッセージを送信する
重要なエラーメッセージをメールで通知したい場合に使用される
HTTPHandler HTTP サーバにログメッセージを送信する
ログメッセージをWebサーバで収集したい場合に使用される

 他のハンドラについては、公式ドキュメントをご覧ください。