【Python】ログの出力してプログラムの実行記録を残す

こんにちは!

みなさんは、アプリケーションを作った際に、ログを出力するようにしていますか?

ログを出力することで、そのアプリケーションがいつ実行されたとか、どんな処理が行われたのかということがわかるようになります。

また、エラーが起きた場合も記録として残すことができるので、どの処理でエラーが起きたのかを素早く把握することができます。

特にエラーの場合、ログがなければ原因を1つ1つ検証していかなければなりません。ログによって原因の把握が容易になり、解決までの時間が大幅に短縮されます。

そこで今回は、Pythonでのログの出力方法を紹介していきます。

Loggingを使う

Pythonでは、loggingというライブラリを使ってログを出力するのが一般的です。

ログはファイルとして出力することができ、任意のメッセージを記録できるほか、変数の中身を記録することもできます。

ログの区分

ログには様々な区分があります。

例えば、プログラムが正常に動作したことを記録することもあれば、異常が起きたことを記録する場合もあります。

これらを全て同じように扱うと、必要な時に欲しい情報が埋もれてしまう可能性があります。

(例えば、ごく稀に発生した以上のログが普段の正常なログに埋もれてしまうなど)

これを防ぐために、ログの区分や重要度が分かれています

DEBUG

エラーの原因を特定したい場合に必要な詳細情報

INFO

プログラムが正常に実行されたことを確認する

WARNING

想定外の問題が生じた、または近く起こりそう。プログラムは実行される。(例:新しいバージョンのライブラリでは動作しないコードがある等)

ERROR

問題が発生し、プログラム中の機能を実行できない

CRITICAL

プログラム自体が実行できない重大なエラー

設定

loggingでログを出力するためには、最初に設定を記述する必要があります。

基本的には、以下をおまじないと思ってコピペすれば動くとは思います。ファイル名などは適宜変更してください。

import logging

# インスタンスの作成
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# "example.log"を出力先とするファイルハンドラ作成
ch = logging.FileHandler(filename="example.log")
#DEBUGレベルまで見る
ch.setLevel(logging.DEBUG)

# ログの記述フォーマット
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# ファイルハンドラにフォーマット情報を与える
ch.setFormatter(formatter)

# logger(インスタンス)にファイルハンドラの情報を与える
logger.addHandler(ch)

上記の設定では、プログラムを実行すると、example.logにそのプログラムのログが記録されます

ログの形式は、任意に指定することができます。上記では、formatterの部分で指定しています。

ログの出力

ここまでの設定を記述した後は、実際にログを出力する部分を記述しましょう。

今回はテストとして、全てのレベルのログを出力します。

logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

これを実行すると、example.logにはログが記述されます。

ログへの出力結果

setLevelを変更することで、ログに出力するレベルを指定することができます。

試しに、ERROR以上のログだけを出力するように指定してみます。

import logging

# インスタンスの作成
logger = logging.getLogger(__name__)
logger.setLevel(logging.<span class="red">ERROR</span>)

# "example.log"を出力先とするファイルハンドラ作成
ch = logging.FileHandler(filename="example.log")
#DEBUGレベルまで見る
ch.setLevel(logging.<span class="red">ERROR</span>)

# ログの記述フォーマット
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# ファイルハンドラにフォーマット情報を与える
ch.setFormatter(formatter)

# logger(インスタンス)にファイルハンドラの情報を与える
logger.addHandler(ch)


logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

#クローズ
logger.removeHandler(ch)
ch.close()
ログへの出力結果

まとめ

Pythonでのログの出力方法を紹介しました。

とりあえず簡単なアプリケーションやプログラムであれば、今回の方法で十分使えるのではないかなと思います。

適切な箇所でログを吐くようにしておかないと、何かあったときにとても困ります^^;

保守のことも考えて、しっかりログを残すようにしておきましょう。

ではでは👋