📝

loggingの簡単な使い方

2024/01/08に公開

はじめに

こんにちは、@nano_sudoです!
今回は、ライブラリ紹介シリーズ第3弾として、loggingを紹介します!
loggingは、Pythonの標準ライブラリでありながら、とても強力な機能を持っています。
今回は、初心者の方でも簡単に理解できるように、loggingの基本的な使い方を紹介します。

loggingとprintの違い

  • print

    • 主にデバッグ用
    • ログレベルを指定できない
  • logging

    • ログレベルを指定できる
    • ログをファイルに出力できる
    • ログのフォーマットを指定できる
    • ログの出力先を複数指定できる
    • かっこいいログを出力できる(外部ライブラリ使用)

インストール

loggingは、Pythonの標準ライブラリなので、インストールは不要です。

loggingの基本的な使い方

各種ログレベルの出力

loggingには、以下のようなログレベルがあります。(下に行くほどレベルが高い)

  • DEBUG
    問題の診断のときに興味のある詳細情報を記録するために使用します。
  • INFO
    正常な動作を示す情報を記録するために使用します。
  • WARNING
    問題が発生したことを示す警告を記録するために使用します。(例:ディスク空き容量が少ない)
  • ERROR
    重大な問題によって、ある機能を実行できないときに使用します。
  • CRITICAL
    プログラム自体が実行を続行できない重大な問題が発生したときに使用します。

使い方

import logging

# ログレベルを設定
logging.basicConfig(level=logging.DEBUG) # これは後で説明します

# 各種ログレベルの出力
# debug
logging.debug("debug")

# info
logging.info("info")

# warning
logging.warning("warning")

# error
logging.error("error")

# critical
logging.critical("critical")

# f-stringを使うこともできる
name = "Alice"
logging.info(f"Hello, {name}!")

ロガーの作成・取得

loggingには、getLogger()という関数があります。
この関数を使うと、ロガーを作成・取得することができます。
getLogger()の引数には、ロガーの名前を指定します。名前が存在しない場合は、新しくロガーが作成されます。
ロガーの名前は、__name__(現在のモジュール名)を指定するのが一般的です。

これを利用して、モジュールごとにロガーを作成することができます。

使い方

hello.py
import logging

def say_hello():
    # ロガーの取得
    logger = logging.getLogger(__name__)
    logger.info("Hello, World!")

main.py
import logging
from hello import say_hello

# ロガーの設定
logging.basicConfig(level=logging.INFO)

# ロガーの取得
logger = logging.getLogger(__name__)

# モジュールの実行
say_hello()

実行結果

INFO:hello:Hello, World!

ロガーを設定する

loggingには、basicConfig()という関数があります。
この関数を使うと、ロガーの設定を行うことができます。

引数

  • level [int] [logging.<level>]
    ログレベルを指定します。
    ログレベルには、以下のようなものがあります。

    • logging.DEBUG
    • logging.INFO
    • logging.WARNING
    • logging.ERROR
    • logging.CRITICAL
      指定したログレベル以上のログが出力されます。
      (例:ログレベルをINFOに設定した場合、INFOWARNINGERRORCRITICALのログが出力されます。)
  • format [str]
    ログのフォーマットを指定します。
    ログのフォーマットには、以下のようなプレースホルダーを指定することができます。

    • %(asctime)s
      ログを出力した日時を指定します。
    • %(levelname)s
      ログレベルを指定します。
    • %(name)s
      ロガーの名前を指定します。
    • %(message)s
      ログのメッセージを指定します。
  • datefmt
    ログの日時のフォーマットを指定します。
    ログの日時のフォーマットには、strftime()と同じフォーマットを指定することができます。
    くわしくは、こちらをご覧ください。

  • handler , formatter
    発展的な内容になるので、ここでは紹介しません。

使い方

import logging

# ロガーの設定
logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s %(levelname)s %(name)s %(message)s"
    datefmt="[%X]"
)

発展的な使い方

色付きのログを出力する

個人的に、richを使うのがおすすめです。
richを使えば、簡単に色付きのログを出力することができます。
また、右端にどこからログが出力されたかが表示されるので、どこからログが出力されたかわかりやすくなります。

インストール

pip install rich

or

poetry add rich

引数

RichHandler

  • markup [bool]
    マークアップを有効にするかどうかを指定します。
    マークアップを有効にすると、色付きのログを出力することができます。
    数字や真偽値に色が付きます。
    例えば、[red]hello[/red]のようにすると、色付きのログを出力することができます。
    ログレベルはFalseでも色がつきます。
  • rich_tracebacks [bool]
    トレースバックをかっこよく表示するかどうかを指定します。
    トレースバックをかっこよく表示すると、トレースバックが見やすくなります。

使い方

import logging
from rich.logging import RichHandler

# ロガーの設定
logging.basicConfig(
    level=logging.DEBUG,
    format="%(message)s",
    datefmt="[%X]",
    handlers=[RichHandler(markup=True,rich_tracebacks=True)]
)

使ってみたの図

※トレースバックは面倒なので省略しました(殴

Richについて詳しく知りたい方は、以下の記事をご覧ください。

https://zenn.dev/nano_sudo/articles/8a0e60cc24648a

ログをファイルに出力する

loggingには、FileHandlerというクラスがあります。
このクラスを使うと、ログをファイルに出力することができます。

引数

FileHandler

  • filename [str]
    ログを出力するファイル名を指定します。
    ファイル名を指定しない場合は、sys.stderrに出力されます。
  • mode [str]
    ファイルを開くモードを指定します。
    デフォルトはa(追記)です。
    w(上書き)にすると、ログが上書きされます。

使い方

import logging
from logging import FileHandler

# ロガーの設定
logging.basicConfig(
    level=logging.DEBUG,
    format="%(message)s",
    datefmt="[%X]",
    handlers=[FileHandler(filename="log.txt")]
)

ログを複数のファイルに出力する

loggingには、handlersという引数があります。
この引数を使うと、ログを複数のファイルに出力することができます。

使い方

import logging
from logging import FileHandler

# ロガーの設定
logging.basicConfig(
    level=logging.DEBUG,
    format="%(message)s",
    datefmt="[%X]",
    handlers=[
        FileHandler(filename="log.txt"),
        FileHandler(filename="log2.txt")
    ]
)

レベルによって、出力先を変えることもできます。

import logging
from logging import FileHandler

# ロガーの設定

# ログレベルがDEBUGのときは、 debug.log に出力する
# ログレベルがINFOのときは、 info.log に出力する

logging.basicConfig(
    level=logging.DEBUG,
    format="%(message)s",
    datefmt="[%X]",
    handlers=[
        FileHandler(filename="debug.log",level=logging.DEBUG),
        FileHandler(filename="info.log",level=logging.INFO)
    ]
)

もちろん、RichHandlerと組み合わせることもできます。

import logging
from logging import FileHandler
from rich.logging import RichHandler

# ロガーの設定
logging.basicConfig(
    level=logging.DEBUG,
    format="%(message)s",
    datefmt="[%X]",
    handlers=[
        FileHandler(filename="log.txt"),
        RichHandler(markup=True,rich_tracebacks=True)
    ]
)

参考にしたページ

logging --- Python公式ドキュメント

https://docs.python.org/ja/3/library/logging.html

logging howto --- Python公式ドキュメント

https://docs.python.org/ja/3/howto/logging.html

まとめ

お疲れ様でした!
loggingは、Pythonの標準ライブラリでありながら、とても強力な機能を持っています。
loggingを使って、良きPythonライフを送りましょう!
質問やご意見などは、X or コメント欄にてお願いします!

Discussion