🤖

loguruを使ってPythonロガーを簡単に扱おう

に公開

今回は、Pythonのロガーを簡単に利用できるようにしたloguruを紹介しようと思います。

※ 本記事ではサンプルコードの生成のために一部claude codeを利用しています。

Pythonでログを取る方法について

まずはPythonでログを取る方法についてそもそもどうやるのかをみていきましょう。

Pythonには標準機能としてloggingモジュールを使うことが多いと思います。例えば最低限の用意でロガーを用意する場合以下のようにすると作成できます。

default_logging.py
import logging
from logging import getLogger

logging.basicConfig(level=logging.INFO)
logger = getLogger(__name__)
logger.debug("This is debug")
logger.info("This is info")

例えばこれを実行すると以下のようになります。

python default_logging.py

# 結果
DEBUG:__main__:This is debug
INFO:__main__:This is info

この結果ですが、標準出力にうまく連携されていないので、例えばpython default_logging.py | pbcopyのようにしてもクリップボードにはコピーされません。

また、フォーマットの設定をしようとするとFormatterを導入したり、ファイルに出力しようとするとFileHandlerを作成したりと正直かなり厄介になります。

loguruを利用するモチベーション

後ほど実装はお見せしますが、標準のloggingを利用すると記述量が圧倒的に増えてしまうのに対して、loguruではある程度抽象化してくれているので設定がとてもシンプルになります。例えば先ほどの例を書き換えると以下のようになります。

loguru_comp_default_logging.py
import sys
from loguru import logger

logger.remove()
logger.add(sys.stdout, level="INFO")
logger.add(level="DEBUG")
logger.debug("This is debug")
logger.info("This is info")

この例だけ見ると、「なんだ、量増えてるじゃん」と思われるかもしれませんが、フォーマッターとかを入れたりすると一気に簡単になるので紹介します。

https://github.com/Delgan/loguru

loguru使ってみる

インストール

以下のようにすると環境を構築できます。

uv init loguru_test -p 3.12
cd loguru_test
uv add loguru

ローテーションの実装

まずはログローテーションをする例をみてみましょう。まずは例として1MBごとに新しいファイルにログを残すコードを実装してみます。まずはloggingを使う例をみてみましょう。なお、最初に言及したようにloggingを使うのは大変なので、皆さんの友達claude codeを利用しました。

default_logging_rotation.py
import logging
from logging.handlers import RotatingFileHandler
import os

def setup_rotating_logger():
    logger = logging.getLogger('rotating_logger')
    logger.setLevel(logging.INFO)
    
    log_dir = 'logs'
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    
    handler = RotatingFileHandler(
        filename=os.path.join(log_dir, 'app.log'),
        maxBytes=1024*1024,  # 1MB
        backupCount=5
    )
    
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    handler.setFormatter(formatter)
    
    logger.addHandler(handler)
    
    return logger

if __name__ == "__main__":
    logger = setup_rotating_logger()
    
    # テスト用のログ出力
    for i in range(10000):
        logger.info(f"This is log message {i}")
        logger.warning(f"This is warning message {i}")
        logger.error(f"This is error message {i}")
    
    print("ログファイルが作成されました。logsディレクトリを確認してください。")

容量に応じてログローテーションをするために以下のように実装しています。手順としては以下になりますね。

  1. ローテーションをするためにファイルハンドラーを作成する
  2. ハンドラーにログのフォーマッターを設定する
  3. ファイルハンドラーをロガーに設定する
handler = RotatingFileHandler(
    filename=os.path.join(log_dir, 'app.log'),
    maxBytes=1024*1024,  # 1MB
    backupCount=5
)

formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)

logger.addHandler(handler)

こちらを実行すると、logsフォルダにログが生成され、1MBを超えるとそれまでログを記録していたファイルが末尾に通し番号をつけた上でファイルがローテーションされます(例えばlogs/app.log.1)。

それではこれと全く同じことをloguruを使って実装します。実装は以下になります。

loguru_rotation.py
import sys
from loguru import logger
import os

def setup_rotating_logger():
    logger.remove()
    logger.add(sys.stdout, colorize=True, format="{time} - {name}:{line} - {level} - {message}", level="INFO")
    logger.add(os.path.join("logs", "app.log"), rotation="1 MB", retention=2)

    log_dir = 'logs'
    if not os.path.exists(log_dir):
        os.makedirs(log_dir)
    

if __name__ == "__main__":
    setup_rotating_logger()
    
    # テスト用のログ出力
    for i in range(10000):
        logger.info(f"This is log message {i}")
        logger.warning(f"This is warning message {i}")
        logger.error(f"This is error message {i}")
    
    print("ログファイルが作成されました。logsディレクトリを確認してください。")

どうでしょう?パッとみてもとてもシンプルになっていることがわかるかと思います。loguruでは設定の反映を基本的にlogger.addで集約させられています。これのおかげでまとめて設定を反映させることができます。出力フォーマットとローテーションの設定を合わせても2行で対応できています。ちなみにフォーマットを設定する前はカラーリングが自動で作成されますが、フォーマットを指定すると色を自分で指定する必要があります。

logger.add(sys.stdout, colorize=True, format="{time} - {name}:{line} - {level} - {message}", level="INFO")
logger.add(os.path.join("logs", "app.log"), rotation="1 MB", retention=2)

まとめ

今回はPythonでロガーをシンプルに扱えるloguruを紹介しました。紹介した機能意外にも色々用意されており、どれもほとんどがlogger.addの形式で設定でき、とても扱いやすくなっております。直接loggingを利用しなくてもいい感じに実装できるのでぜひ参考にしてください。

Discussion