この記事はChatGPTを使用して作成しています。
はじめに
Pythonのloggingモジュールは、単なるprint
文に比べてはるかに柔軟かつ強力なログ管理機能を提供します。
- ログレベルの管理: ログの重要度に応じて、DEBUG、INFO、WARNING、ERROR、CRITICALといったレベルを使い分けることができ、必要な情報だけを抽出できます。
- 多様な出力先: コンソール、ファイル、さらには外部サービス(例:Slack)など、複数の出力先を同時に設定可能です。
- フォーマットのカスタマイズ: ログメッセージの形式を自由に設定できるため、後からの解析やデバッグが容易になります。
loggingの基本的な使い方
以下は、loggerを用いた基本的なログ出力のサンプルコードです。
import logging
# ロガーの生成とレベル設定
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
# コンソールハンドラの設定
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# フォーマッタの設定
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
# ハンドラをロガーに追加
logger.addHandler(ch)
# ログの出力
logger.debug("デバッグメッセージ")
logger.info("情報メッセージ")
logger.warning("警告メッセージ")
logger.error("エラーメッセージ")
logger.critical("致命的なメッセージ")
このコード例から分かるように、loggerによるログ出力は大きく分けて以下の4つの流れで行われます。
- ロガーの生成とレベル設定
- ハンドラの設定
- フォーマッタの設定
- ログの出力
これから各流れについて詳しく掘り下げて説明していきます。
1. ロガーの生成とレベル設定
ロガーの生成は、以下のコードで行います。
logger = logging.getLogger(__name__)
※ logging.debug("デバッグメッセージ")
のように、ロガーを生成しなくてもログを生成することはできますが、設定の柔軟性や一貫性の観点から推奨されません。
詳細はこちら
Pythonのloggingモジュールには、主に以下の5つのログレベルがあります。
レベル | 値 | 説明 |
---|---|---|
DEBUG | 10 | 詳細な情報。主に開発や問題解決のために使用。 |
INFO | 20 | 通常の動作状況など、一般的な情報を記録。 |
WARNING | 30 | 警告。予期しない事象や潜在的な問題を示す。 |
ERROR | 40 | エラー。実行時に問題が発生した場合に記録。 |
CRITICAL | 50 | 致命的なエラー。システム全体の障害など、非常に重大な問題を示す。 |
出力レベルのセットは、以下の一行のコードで行います。
logger.setLevel(logging.INFO)
これにより、INFO
未満のレベルのログは出力されなくなります。
2. ハンドラの設定
Handlerを利用することで、ログの出力先や出力レベルを細かく制御することができます。
使用するHandlerによってログの出力先が変わります。以下は一般的なHandlerの一覧です。
Handlerタイプ | 説明 |
---|---|
StreamHandler |
コンソールなどのストリームに出力します。 |
FileHandler |
ファイルにログを出力します。 |
RotatingFileHandler |
ファイル出力をローテーションして管理します。 |
TimedRotatingFileHandler |
時間単位でファイル出力をローテーションします。 |
SMTPHandler |
メールでログを送信します。 |
Handler単位で出力レベルを制御できます。以下は、Handlerのみを設定するコード例です。
import logging
# コンソールハンドラの設定
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# ファイルハンドラの設定
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.DEBUG)
以下は、コンソールにINFO以上のレベルのログを出力し、ファイルにDEBUG以上のレベルのログを出力する完全なコード例です。
入力
import logging
# ロガーの生成
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
# コンソールハンドラの設定
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_formatter = logging.Formatter('%(levelname)s - %(message)s')
console_handler.setFormatter(console_formatter)
# ファイルハンドラの設定
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)
# ハンドラをロガーに追加
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 入力例と出力例
logger.debug("デバッグメッセージ")
logger.info("情報メッセージ")
logger.error("エラーメッセージ")
出力(コンソール)
INFO - 情報メッセージ
ERROR - エラーメッセージ
出力(ファイル: app.log)
2025-04-04 12:00:00,000 - DEBUG - デバッグメッセージ
2025-04-04 12:00:00,000 - INFO - 情報メッセージ
2025-04-04 12:00:00,000 - ERROR - エラーメッセージ
3. フォーマッタの設定
フォーマッタを使用することで、ログの出力形式を細かくカスタマイズできます。たとえば、ログにタイムスタンプやロガー名、ログレベルを含めることで、後からの解析やデバッグが容易になります。
以下は、フォーマッタで設定可能な主なフォーマット指定子の一覧です。
指定子 | 説明 | 例 |
---|---|---|
%(asctime)s |
ログ出力時刻 | 2025-04-04 12:00:00,000 |
%(name)s |
ロガーの名前 | my_logger |
%(levelname)s |
ログレベル | INFO, DEBUG, ERROR など |
%(message)s |
ログメッセージの内容 | 任意のメッセージ |
%(filename)s |
ログを出力したファイル名 | example.py |
%(lineno)d |
ログ出力行番号 | 42 |
フォーマッタをハンドラにセットするコードは以下のようになります。
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
4.ログの出力
ログの出力には以下の関数を使います。
関数 | ログレベル |
---|---|
logger.debug() | DEBUG |
logger.info() | INFO |
logger.warning() | WARNING |
logger.error() | ERROR |
logger.critical() | CRITICAL |
ログの出力は、以下のコードで行います。
import logging
# ロガーの生成とレベル設定
logger = logging.getLogger('output_logger')
logger.setLevel(logging.DEBUG)
# 各ログレベルでの出力例
logger.debug("これはDEBUGメッセージです。")
logger.info("これはINFOメッセージです。")
logger.warning("これはWARNINGメッセージです。")
logger.error("これはERRORメッセージです。")
logger.critical("これはCRITICALメッセージです。")
Loggerの主要属性とメソッドの概要
以下は、loggerの主要な属性やメソッドを引数も含めた形でまとめた表です。
属性/メソッド | 引数 (必要な場合) | 説明 |
---|---|---|
logger.name |
なし | ロガーの名前。通常はモジュール名が設定される。 |
logger.level |
なし | 現在のログレベルを示す。 |
logger.setLevel() |
level |
ログレベルを設定する。例: logger.setLevel(logging.DEBUG)
|
logger.addHandler() |
handler |
ハンドラを追加し、ログの出力先を指定する。 |
logger.removeHandler() |
handler |
既存のハンドラを削除する。 |
logger.debug() |
msg |
DEBUGレベルのログを出力する。 |
logger.info() |
msg |
INFOレベルのログを出力する。 |
logger.warning() |
msg |
WARNINGレベルのログを出力する。 |
logger.error() |
msg |
ERRORレベルのログを出力する。 |
logger.critical() |
msg |
CRITICALレベルのログを出力する。 |
上級
YAMLによるログ設定の管理
YAMLファイルを用いてログ設定を管理することで、設定内容の見通しが良くなり、環境ごとに柔軟な変更が可能となります。
以下に、YAML設定ファイルの例と、それを読み込んで実行するコード例を示します。
YAML設定ファイル例 (logging_config.yaml
)
version: 1
formatters:
simple:
format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: simple
stream: ext://sys.stdout
file:
class: logging.FileHandler
level: DEBUG
formatter: simple
filename: app.yaml.log
loggers:
my_logger:
level: DEBUG
handlers: [console, file]
propagate: no
root:
level: WARNING
handlers: [console]
YAML設定を用いたコード例
import logging
import logging.config
import yaml
with open('logging_config.yaml', 'r') as f:
config = yaml.safe_load(f)
logging.config.dictConfig(config)
logger = logging.getLogger('my_logger')
logger.debug("YAML設定によるデバッグメッセージ")
logger.info("YAML設定による情報メッセージ")
import yaml
の実行には、事前にpip install pyyaml
が必要であることに注意してください。
出力(コンソール)
INFO - YAML設定による情報メッセージ
出力(ファイル: app.yaml.log)
2025-04-04 12:00:00,000 - DEBUG - YAML設定によるデバッグメッセージ
2025-04-04 12:00:00,000 - INFO - YAML設定による情報メッセージ
YAML設定キーの概要
YAML設定ファイルで使用される主要なキーを以下の表にまとめます。
キー | 説明 |
---|---|
version | 設定のバージョン。通常は 1 を指定。 |
formatters | ログメッセージのフォーマットを定義。 |
handlers | ログの出力先(例:コンソール、ファイル)を定義。 |
loggers | 個別のロガー設定を定義。 |
root | ルートロガーの設定。 |
class | ハンドラのクラス名。例:logging.StreamHandler 、logging.FileHandler 。 |
level | 各ハンドラまたはロガーのログレベルを指定。 |
formatter | 使用するフォーマッタのキーを指定。 |
filename | ファイルハンドラの場合、出力先ファイル名を指定。 |
stream | ストリームハンドラの場合、出力先を指定(例:ext://sys.stdout )。 |
カスタムハンドラの作成:Slack通知ハンドラ
以下は、SlackのWebhook URLを使用してエラー発生時にアラートを送信するカスタムハンドラの例です。
環境変数や設定ファイルでSLACK_WEBHOOK_URL
などを管理することを推奨します。
import logging
import json
import requests
class SlackHandler(logging.Handler):
def __init__(self, webhook_url, level=logging.NOTSET):
super().__init__(level)
self.webhook_url = webhook_url
def emit(self, record):
log_entry = self.format(record)
payload = {"text": log_entry}
try:
response = requests.post(
self.webhook_url,
data=json.dumps(payload),
headers={'Content-Type': 'application/json'}
)
response.raise_for_status()
except Exception:
self.handleError(record)
# 使用例
logger = logging.getLogger('slack_logger')
logger.setLevel(logging.ERROR) # エラー以上のログのみ通知
# 環境変数等からWebhook URLを取得する例
SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"
slack_handler = SlackHandler(SLACK_WEBHOOK_URL)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
slack_handler.setFormatter(formatter)
logger.addHandler(slack_handler)
logger.error("Slackに送信されるエラーメッセージ")
スラック通知の出力例
実際にエラーが発生すると、設定したSlackのWebhook URLに対して以下のようなペイロードが送信されます。
{
"text": "2025-04-04 12:00:00,000 - ERROR - Slackに送信されるエラーメッセージ"
}
参考サイト