基礎から学ぶPython入門 90日コース | 実践Python - Day 27:ログ

90日で身につけるPython
スポンサーリンク
スポンサーリンク

Day 27:ログで「あとから原因を追えるコード」にする

Day 27では、Python標準ライブラリの logging を使って、 DEBUG / INFO / WARNING / ERROR / ログファイル というキーワードを軸に、 「あとから原因を追えるコード」を書く感覚を身につけていきます。

ログとは何か:コードの「足跡」を残すもの

printとの違いをイメージする

プログラムの動きを確認するとき、多くの方が最初に使うのは print だと思います。

print("処理を開始します")
print("ユーザーID:", user_id)
print("処理が完了しました")
Python

print は手軽ですが、次のような問題があります。

  • どこで何が出力されているか管理しづらい
  • 本番環境では「画面に出るだけ」で、あとから追いづらい
  • 重要度(ただの情報なのか、エラーなのか)が区別されない

そこで登場するのが ログ です。

  • ログは「プログラムの動きを記録する仕組み」
  • 重要度(レベル)を付けて記録できる
  • ファイルに書き出して、あとから分析できる

という特徴があります。

loggingモジュールの基本を押さえる

最初の一歩:基本的なログ出力

Pythonには、ログを扱うための標準モジュール logging が用意されています。

import logging

# ログの基本設定を行います。
logging.basicConfig(level=logging.INFO)

logging.debug("これはDEBUGレベルのログです")
logging.info("アプリケーションを開始します")
logging.warning("設定ファイルが見つかりません。デフォルト設定を使用します")
logging.error("データベース接続に失敗しました")
Python

ここでのポイントは次の通りです。

  • logging.basicConfig(level=logging.INFO)
    • 「INFO以上のログを表示する」という設定です。
    • DEBUG はそれより下のレベルなので、この設定では表示されません。
  • logging.debug(...) / info(...) / warning(...) / error(...)
    • ログレベルごとにメソッドが用意されています。

実行すると、ターミナルに次のような出力が表示されます(環境によって多少異なります)。

INFO:root:アプリケーションを開始します
WARNING:root:設定ファイルが見つかりません。デフォルト設定を使用します
ERROR:root:データベース接続に失敗しました

ログレベルを理解する:DEBUG〜ERRORの役割

代表的なログレベル

logging には、代表的に次のログレベルがあります。

  • DEBUG
    • 開発中に細かい動きを追いたいときのログ
    • 変数の中身・処理の途中経過など
  • INFO
    • 通常の動作を記録するログ
    • アプリの起動・終了、重要な処理の開始・完了など
  • WARNING
    • 「今は動いているが、問題の兆候がある」ログ
    • 設定ファイルが見つからない、古いAPIを使っているなど
  • ERROR
    • 「処理が失敗した」ログ
    • 例外が発生した、外部サービスに接続できないなど

レベルによるフィルタリング

basicConfiglevel で「どのレベル以上を出すか」を指定できます。

logging.basicConfig(level=logging.DEBUG)   # DEBUG以上(全部)を出す
logging.basicConfig(level=logging.INFO)    # INFO以上(INFO, WARNING, ERROR)を出す
logging.basicConfig(level=logging.WARNING) # WARNING以上(WARNING, ERROR)を出す
Python

開発中は DEBUG を出し、本番環境では INFO 以上にする、といった使い分けがよく行われます。

ログファイルに書き出す:あとから読み返せるようにする

basicConfigでファイル出力を設定する

ログを画面に出すだけでなく、ファイルに保存することが重要です。 basicConfigfilename を指定すると、ログをファイルに書き出せます。

import logging

logging.basicConfig(
    level=logging.DEBUG,              # DEBUG以上のログを記録します
    filename="app.log",               # ログファイル名
    filemode="a",                     # 追記モード ("w" にすると毎回上書き)
    format="%(asctime)s [%(levelname)s] %(message)s"  # ログの書式
)

logging.debug("デバッグ情報です")
logging.info("アプリケーションを開始します")
logging.warning("設定ファイルが見つかりません")
logging.error("致命的なエラーが発生しました")
Python

このコードを実行すると、カレントディレクトリに app.log が作成され、次のような内容が記録されます。

2026-08-30 09:39:00,123 [DEBUG] デバッグ情報です
2026-08-30 09:39:00,124 [INFO] アプリケーションを開始します
2026-08-30 09:39:00,125 [WARNING] 設定ファイルが見つかりません
2026-08-30 09:39:00,126 [ERROR] 致命的なエラーが発生しました

ここでのポイントは、

  • filename で「どのファイルに書くか」を指定していること
  • format で「日時・レベル・メッセージ」を含む書式を指定していること
  • ログファイルをあとから開いて、「いつ・何が起きたか」を追えるようになること

です。

ロガーを使って「モジュールごと」にログを分ける

loggerオブジェクトを作る

少しだけ踏み込んで、logging.getLogger() を使った書き方も見ておきます。 これにより、「モジュールごと・機能ごと」にロガーを分けることができます。

import logging

# ログの基本設定
logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s [%(name)s] [%(levelname)s] %(message)s"
)

# ロガーを取得します(名前を付けられます)。
logger = logging.getLogger("app")

logger.debug("デバッグ情報です")
logger.info("アプリケーションを開始します")
logger.warning("設定ファイルが見つかりません")
logger.error("致命的なエラーが発生しました")
Python

出力例:

2026-08-30 09:39:00,123 [app] [DEBUG] デバッグ情報です
2026-08-30 09:39:00,124 [app] [INFO] アプリケーションを開始します
2026-08-30 09:39:00,125 [app] [WARNING] 設定ファイルが見つかりません
2026-08-30 09:39:00,126 [app] [ERROR] 致命的なエラーが発生しました

ここでのポイントは、

  • getLogger("app") で「名前付きロガー」を作っていること
  • ログ出力に name が含まれることで、「どのロガーから出たログか」が分かること

です。 大きなアプリでは、getLogger(__name__) を使って「モジュールごとにロガーを持つ」ことがよくあります。

ログと例外処理を組み合わせる

try/exceptでエラーをログに残す

ログは、例外が発生したときの情報を残すのにも役立ちます。

import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s"
)

logger = logging.getLogger("app")


def divide(a, b):
    """割り算を行う関数です。"""
    return a / b


def main():
    logger.info("アプリケーションを開始します")

    try:
        result = divide(10, 0)  # ゼロ除算で例外が発生します
        logger.info("計算結果: %s", result)
    except ZeroDivisionError as e:
        logger.error("ゼロ除算が発生しました: %s", e)

    logger.info("アプリケーションを終了します")


if __name__ == "__main__":
    main()
Python

出力例:

2026-08-30 09:39:00,123 [INFO] アプリケーションを開始します
2026-08-30 09:39:00,124 [ERROR] ゼロ除算が発生しました: division by zero
2026-08-30 09:39:00,125 [INFO] アプリケーションを終了します

ここでのポイントは、

  • 例外が発生したときに logger.error(...) で「何が起きたか」を記録していること
  • ログを見れば、「どのタイミングで、どんなエラーが起きたか」が分かること

です。

Day 27ミニテンプレート:ログ入門スクリプト

最後に、Day 27で学んだ内容をまとめて試せる「ログ入門スクリプト」のテンプレートを示します。

# day27_logging.py
# logging入門の練習用スクリプト

import logging

def setup_logger():
    """ロガーの基本設定を行う関数です。"""
    logging.basicConfig(
        level=logging.DEBUG,  # DEBUG以上のログを記録します
        filename="app.log",   # ログファイル名
        filemode="a",         # 追記モード
        format="%(asctime)s [%(name)s] [%(levelname)s] %(message)s"
    )
    return logging.getLogger("app")


def divide(a, b):
    """割り算を行う関数です。"""
    return a / b


def main():
    logger = setup_logger()

    logger.info("アプリケーションを開始します")

    logger.debug("10 / 2 の計算を行います")
    result1 = divide(10, 2)
    logger.info("10 / 2 の結果: %s", result1)

    logger.debug("10 / 0 の計算を行います(エラーの例)")
    try:
        result2 = divide(10, 0)
        logger.info("10 / 0 の結果: %s", result2)
    except ZeroDivisionError as e:
        logger.error("ゼロ除算が発生しました: %s", e)

    logger.warning("このあとアプリケーションを終了します")
    logger.info("アプリケーションを終了します")


if __name__ == "__main__":
    main()
Python

このスクリプトを実行すると、

  • ターミナルにはログが表示され
  • 同時に app.log にもログが記録されます

あとから app.log を開いて、「どんな処理が行われ、どこでエラーが起きたか」を確認できるようになります。

Day 27のまとめ

Day 27では、ログ入門として、

  • ログ=「プログラムの足跡を残す仕組み」というイメージ
  • logging モジュールで、DEBUG / INFO / WARNING / ERROR を使い分ける方法
  • basicConfig でログレベル・書式・ファイル出力を設定する基本
  • getLogger で名前付きロガーを作り、モジュールごとにログを分ける考え方
  • 例外処理とログを組み合わせて、「エラーの原因をあとから追える」コードにする方法

をステップバイステップで体験していただきました。

ここまで来ると、「ただ動くコード」から一歩進んで、「あとから原因を追えるコード」を意識して書く感覚が少し育っているはずです。 この感覚は、今後の実践Python編で、規模の大きなアプリケーションや本番環境を扱うときに、トラブルを素早く発見・修正するための大きな武器になっていきます。

タイトルとURLをコピーしました