Pythonで様々なデータ処理を実装していると「ここまでの処理はうまく実装できているかな?」と思い、計算結果などをprint()で出力するような実装は、小規模なプログラムではよく行うと思います。
一方で大規模なプログラムを書いたり、他の人が実装したライブラリなどを利用するとき、途中経過の処理出力をprint() だけでは処理するのが難しく、logging と呼ばれるログ処理用のライブラリを利用することがあります。logging自体は設定が複雑なものですが、ここではprint()を使わない最初の一歩目として、基本的な使い方を確認します。
loggingをprintの代わりに使ってみる
細かい設定はいろいろと可能ですが、とりあえずprintで処理していたものをloggingに置き換えると、ログ処理の最初の一歩になります。loggingを利用するとき、ログとして残したい内容のレベルに応じて、debug/info/warning/error/criticalというレベルを設定します。サンプルで使い方を見てみましょう。
サンプルソース
サンプルの実装です。
- logging をインポートします
- debug/info/warning/error/ciritical のレベルでログを出力します
- 名前付きのメソッドではなく、logメソッドにレベルを渡しても同じように出力できます
実行結果
サンプルを実行した結果を確認します。

端末には warning、error、critical、そして同じ実装を行った warningの2回目、がそれぞれ出力されました。通常のprint() とは異なり、WARNING:root:warning のように情報がおまけで付与されています。またdebugとinfoは端末には出力されていないことが分かります。
これはデフォルトの設定では、debugとinfoの情報(動作確認や正常動作の結果)を保存しない(ログとして残さない)ようになっているためです。またログの出力先は、デフォルトの状態では端末にそのまま出力されています。
ログの設定を変更する
以下の例では、ログの設定を変え、ログの出力がどのように変化するかを確認してみます。
ログをファイルに出力するサンプルソース
プログラムを実行したとき、何かのログファイルがディレクトリや/tmp/logなどに保存されたのを見たことがあるかもしれません。似たことをpythonのloggingでも実装してみます。
logging.basicConfigを利用して、出力先を端末からファイル(error.log)に変更しました。
実行結果
上のプログラムを実行しても端末には何も表示されませんが、代わりに error.log が次のように書き込まれています。

このプログラムを3回実行すると、3回分のログが残ることが分かります。このように情報をファイルに保存しておくことで、後ほど役に立つことがあるかもしれないですね。その代わり、いつ実行したログなのかわかりづらくなってしまったので、basciConfigを少し編集してみます。
ログをファイルに情報付きで出力するサンプルソース
サンプルの実装です。
ここでは
- formatとdatefmtを設定した
- formatは [ログのレベル] (時間) | ログの出力内容 とした
- datafmtは日時と時間を設定した
というような意味があります(細かい設定は公式のマニュアルをご確認下さい)。
実行結果
プログラムを3回実行した後のログファイル(error.log)の内容です。フォーマット付きのログが残ったことが分かります。
スポンサーリンク

ログを端末とファイルの両方に出力するサンプルソース
最後にprint()のログの代わりで、ファイルに記録しつつ、端末にもログを出力し、infoとdebugも含めて全部のメッセージを保存するようにしてみます。
ここでは
- ログ出力のレベルはDEBUG以上全てに設定しました
- ログ出力先(ハンドラ)は端末(StreamHandler)とファイル(FileHandler ファイル名 error.log)に設定しました。
実行結果
プログラムを実行すると、端末には次のようにログが全て出力されることが分かります。

端末から2回プログラムを実行すると、ファイルは次のようになっています。

このように logging を利用することで、print() よりも複雑にログ情報を残すことができます。
logging は複雑な設定や他ファイル・プログラムとの連携など細かい設定もありますが、気軽に利用してもプログラムの開発に役に立つと思いますので、一度使ってみてくださいね。