基礎

Pythonロギング入門!loggingモジュールの使い方

Python

Pythonロギング入門!
loggingモジュールの使い方

print文の代わりにloggingモジュールを使って、本格的なログ管理を実現しましょう。

こんな人向けの記事です

  • print文でのデバッグから卒業したい人
  • 本番環境でのログ管理を学びたい人
  • ログレベルやハンドラの設定を知りたい人

Step 1loggingの基本

Python
import logging

# 基本設定
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

# printの代わりにloggerを使う
logger.debug("デバッグ情報")
logger.info("処理が完了しました")
logger.warning("ディスク使用量が80%を超えました")
logger.error("データベース接続に失敗")
logger.critical("システムが停止しました")
printとの違い
loggingはレベル制御、ファイル出力、フォーマット、ローテーションなど本格的なログ管理機能を提供します。

Step 2ログレベル

Python
import logging

# ログレベル(低い順)
# DEBUG    (10): 開発時の詳細情報
# INFO     (20): 正常動作の確認
# WARNING  (30): 潜在的な問題(デフォルト)
# ERROR    (40): エラー発生
# CRITICAL (50): 致命的エラー

# レベルを設定(設定レベル以上のみ出力)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

logger.debug("これは表示されない")   # INFOより低いので非表示
logger.info("これは表示される")      # INFO以上なので表示
logger.warning("これも表示される")   # INFO以上なので表示

# 環境に応じてレベルを切り替え
import os
log_level = os.environ.get("LOG_LEVEL", "INFO")
logging.basicConfig(level=getattr(logging, log_level))

Step 3フォーマットの設定

Python
import logging

# フォーマットをカスタマイズ
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
)

logger = logging.getLogger("myapp")
logger.info("サーバー起動")
# 出力: 2026-02-19 10:30:00 [INFO] myapp: サーバー起動

# 主なフォーマット変数
# %(asctime)s    : 日時
# %(levelname)s  : ログレベル名
# %(name)s       : ロガー名
# %(filename)s   : ファイル名
# %(lineno)d     : 行番号
# %(funcName)s   : 関数名
# %(message)s    : メッセージ

Step 4ファイル出力とハンドラ

Python
import logging

logger = logging.getLogger("myapp")
logger.setLevel(logging.DEBUG)

# コンソール出力用ハンドラ
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_fmt = logging.Formatter("%(levelname)s: %(message)s")
console_handler.setFormatter(console_fmt)

# ファイル出力用ハンドラ
file_handler = logging.FileHandler("app.log", encoding="utf-8")
file_handler.setLevel(logging.DEBUG)
file_fmt = logging.Formatter(
    "%(asctime)s [%(levelname)s] %(name)s %(filename)s:%(lineno)d - %(message)s"
)
file_handler.setFormatter(file_fmt)

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

logger.debug("ファイルのみに出力")
logger.info("コンソールとファイル両方に出力")
logger.error("エラー: コンソールとファイル両方に出力")

Step 5ローテーション

Python
import logging
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler

logger = logging.getLogger("myapp")

# サイズベースのローテーション
size_handler = RotatingFileHandler(
    "app.log",
    maxBytes=10 * 1024 * 1024,  # 10MB
    backupCount=5,               # 最大5世代保持
    encoding="utf-8",
)
# app.log → app.log.1 → app.log.2 ... → app.log.5

# 時間ベースのローテーション
time_handler = TimedRotatingFileHandler(
    "app.log",
    when="midnight",    # 毎日深夜にローテーション
    interval=1,
    backupCount=30,     # 30日分保持
    encoding="utf-8",
)
# when の選択肢: S(秒), M(分), H(時), D(日), midnight, W0-W6(曜日)

logger.addHandler(size_handler)
ログの肥大化に注意
backupCountを設定しないと古いログが削除されず、ディスクを圧迫します。必ず世代数を指定しましょう。

Step 6実践的な設定

Python(dictConfigで設定)
import logging
import logging.config

LOGGING_CONFIG = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "standard": {
            "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
        },
        "detailed": {
            "format": "%(asctime)s [%(levelname)s] %(name)s %(filename)s:%(lineno)d - %(message)s"
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "standard",
        },
        "file": {
            "class": "logging.handlers.RotatingFileHandler",
            "level": "DEBUG",
            "formatter": "detailed",
            "filename": "app.log",
            "maxBytes": 10485760,
            "backupCount": 5,
        },
    },
    "loggers": {
        "myapp": {
            "level": "DEBUG",
            "handlers": ["console", "file"],
        },
    },
}

logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("myapp")

# 例外情報を含めてログ出力
try:
    result = 1 / 0
except ZeroDivisionError:
    logger.exception("計算エラーが発生")
    # スタックトレースが自動的に含まれる

まとめ

  • loggingモジュールでprint文から卒業
  • 5段階のログレベルで出力を制御
  • ハンドラでコンソールとファイルに同時出力
  • RotatingFileHandlerでログのローテーション
  • dictConfigで設定を一元管理