ここではPythonを使ってロギングについて扱っていこうと思います。
プログラムの実行中に起こった出来事の記録をログといい、その記録することをロギングといいます。プログラムの実行時にエラーや意図しない挙動が起こった時に、このログを確認することで不具合の種類を絞り込むことができます。テスト環境などで合わせて使うと便利ですね。
ロギングレベルとその変更
ではロギングについて見ていきましょう。
ロギングには5つのレベルがあり、順に次のような階層になっています。
CRITICAL
ERROR
WARNING
INFO
DEBUG
具体的にコードを書いていきましょう。テキストエディタのAtomを使ってやっていきます。
import logging
logging.critical('critical')
logging.error('error')
logging.warning('warning')
logging.info('info')
logging.debug('debug')
loggingモジュールをインポートして、それぞれのレベルの出力のコードを書いています。
これをPythonファイルに保存してターミナルで実行するとこうなります。(ここでは、ファイル名をlogging_lesson.pyにしています)
出力を見てみると、CRITICAL、ERROR、WARNINGまでは表示されていますが、INFO、DEBUGは表示されていません。
PythonのロギングではデフォルトではINFO、DEBUGは出力されないようになっています。
これを出力するには、レベルを次のように指定するコードを追加する必要があります。
import logging
# logging.basicConfig(level=logging.INFO)
logging.basicConfig(level=logging.DEBUG)
logging.critical('critical')
logging.error('error')
logging.warning('warning')
logging.info('info')
logging.debug('debug')
logging.basicConfig()にlevel=logging.DEBUGと指定すれば、全てのレベルを表示することができます。(INFOまでならlevel=logging.INFOとします)
実行してみましょう。
全てのレベルで出力されました。アプリの開発段階などではここまで出力するようにして使います。公開段階でこのレベルをINFOやWARNINGに変えて運用していくことになると思います。
ロギングの出力のフォーマット
ロギングの出力のフォーマットを見ていきましょう。
次のように.format()を使ったり、%sを使って出力することができます。
import logging
logging.basicConfig(level=logging.INFO)
logging.info('info {}'.format('test infomation'))
logging.info('info %s %s' % ('test', 'infomation'))
#ロギングの時のみの書き方
logging.info('info %s %s', 'test', 'infomation')
実行すると、コンソールには次のようにどれも出力できています。
Python2で使っていた%sをわざわざ.format()で書き換える必要はありません。コードを見かけたとしても変更しなくて大丈夫です。また、最後の%sをカンマ(,)で続けて代入する方法は、ロギングの時のみにできる書き方となっています。
ロギング情報をファイルに出力する
これまではロギングの情報をコンソール画面に出力していましたが、これをファイルに出力する方法を見ておきましょう。
それにはbasicConfig()を次のように書き換える必要があります。
import logging
logging.basicConfig(filename='test_info.log', level=logging.INFO)
logging.info('info %s %s', 'test', 'infomation')
basicConfig()にfilename=’ファイル名’を追加するだけです。このコードだと作業ディレクトリにファイルが作成されます。必要であれば出力用のフォルダを作成しておき、ファイル名の指定部分もパスを含めて記述する必要があります。
このコードを実行すると、test_info.logファイルが作成され、コンソールで表示されたものと同じ記述がファイルの中にあるはずです。
ロギングの書き方
ロギングで出力する情報は、発生した状況がわかるように書けばいいのですが、例えば、ファイルの保存の処理が失敗したというエラーメッセージは、例えば次のように書くことができます。
logging.error('Failed to save the file')
このように単にメッセージ文を記入してもいいわけです。
これを、Key:Valueの辞書型で書くこともあるということも知っておくといいでしょう。
例えば、次のよう形です。
logging.error({
'action': 'save',
'status': 'fail',
'message': 'Failed to save the file'
})
こういう形は、ログの出力をログ解析ソフトを利用して分析する時に強みを発揮します。
ログ解析ソフトは、Key:Valueの形でログを検索するという仕様になっています。
なので、辞書型で書くことがあるということも覚えておきましょう。
まとめ
プログラムの実行中に起こった出来事を記録することをロギングといいます。ここではPythonを使ってそのロギングのレベルと出力について扱いました。
ロギングは開発や運用にあったレベルを指定することになります。
ロギングのフォーマッタ、ロガー、ハンドラ、フィルタ、コンフィグなどは次のように別のところでそれぞれ扱います。
フォーマッタについてはこちらです。
ロガーについてはこちらです。
ハンドラについてはこちらです。
フィルタについてはこちらです。
コンフィグについてはこちらです。
これらの内容も合わせて理解して行きましょう。