プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2021/12/20

[Python] ロギングの個人的ベストプラクティス

update2021/12/24 event_note2021/12/19 23:11

まぁベストかどうかはわかりませんが、現状の私にとっての最適解です。

Python 標準の logging モジュールを使用しますが、logging を直接使うのではなく、getLogger でロガーを取得して使用します。
これについては以下の記事にわかりやすく書いてありました。

このように抽象化しておけば、ロガーハンドラを指定・変更するだけで、ファイルに出力したり、syslog に出力したり、どっかに送信したりと後から簡単に出力先を変更できます。

ロギングの設定をファイルに切り出す

ログに関する設定は logging.yaml というファイルに切り出すことにしました。
これについては以下の記事にわかりやすく書いてありました。

例えばこんな感じです。

from logging import config, getLogger
import yaml

if __name__ == '__main__':

    with open('./logging.yaml', encoding='utf-8') as f:
        logconfig = yaml.safe_load(f)
        config.dictConfig(logconfig)

    logger = getLogger(__name__)

    logger.critical('this is critical')
    logger.error('this is error')
    logger.warning('this is warning')
    logger.info('this is info')
    logger.debug('this is debug')

    try:
        hoge = 0/0
    except Exception as e:
        logger.exception('this is exception')
version: 1
root:
  level: DEBUG
  handlers: [console]
handlers:
  console:
    class: logging.StreamHandler
    stream: ext://sys.stderr
    formatter: myformatter
formatters:
  myformatter:
    format: "%(asctime) [%(levelname:.4)s] %(name)s: %(message)s"

こうしておけば、環境に応じて設定を丸ごと差し替えたりも簡単にできます。
フォーマッタで使える変数については以下を参照してください。

設定いろいろ

ここらへんは環境や好みに応じて様々だと思うので、あくまでサンプルとして。
適宜追加していきます。

コンソール出力をカラフルにして見やすくする

rich を使うのが簡単かつわかりやすかったです。
例えば以下のような感じです。

root:
  level: DEBUG
  handlers: [rich]
handlers:
  rich:
    class: rich.logging.RichHandler
    rich_tracebacks: True

以下の記事も参考にしてください。

syslog に出力する

logging モジュールに SyslogHandler があるので、基本的にこれを指定するだけで OK です。
詳細は別記事にまとめているので、以下を参考にしてください。

flask の出力設定

Flask が HTTP リクエストを受信するたびにログをレベル INFO で出力するので、ERROR 以上のログのみ出力するように設定変更する方法を以下の記事に書いています。