こんにちは、ライターのアキヒロです。
「プログラムが、どうしてこんな動きになっているんだろう」
「変数がどうなってるか知りたいな」
そんなことを考えたことはありませんか?
この記事では、Pythonでログをとるために使う、loggingのformatの使い方について解説します。
この記事では
- loggingを使ってログをとる方法
- formatを変更する方法
といった基本的な内容から
- logging formatをさらに便利に使う方法
まで解説します。
本記事を読む前に、Pythonがどんなプログラミング言語なのかをおさらいしておきたい人は次の記事を参考にしてください。
→ Pythonとは?特徴やできること、活用例をわかりやすく簡単に解説
なお、その他のPythonの記事についてはこちらにまとめています。
ログをとってみよう
print文をプログラムの間に挿入して、動作確認を行ったことはありますか?
print文を使えば、確かに変数の確認や、どこが実行されているかは分かります。
しかし、Pythonにはもっと簡単かつ便利にログをとれる、loggingというモジュールがあるのです!
それでは実際にコードを書いてみましょう。
import logging logger = logging.getLogger(__name__) logging.warning(‘警告!’)
まず、loggingモジュールをインポートしています。
次に、getLogger関数を使ってloggerオブジェクトを宣言しています。引数にはログの出力名を渡します。
最後に、ログメッセージを出力しています。
WARNING:root:警告!
今回はlogging.warning()を使ったので、WARNINGというログメッセージが出力されていることがわかります。
他にも、想定通りのことが起こった時に使うinfo()や、重大な問題が発生したときに使うerorr()などがあります。
ログの出力を変更しよう
loggingで独自のログメッセージを出力できることがわかりました。
しかし、このままではprint文でメッセージを出力することと、あまり変わりません。そこで、次はフォーマットを指定してログメッセージを出力してみましょう!
formatの使い方
では早速、loggingのフォーマットを変更して出力の変化を見てみましょう。
import logging logging.basicConfig(format='%(levelname)s:%(message)s') logger = logging.getLogger(__name__) logger.warning('警告!')
先ほどのコードに一行が加わりました。
loggingのフォーマットはloggingモジュールのbasicConfig関数で指定できます。
levelname,messageについても説明しましょう。
levelnameはログレベルのことです。今回はWARNINGというレベルで出力しているため、levelnameにはWARNINGが出力されるはずです。
messageは名前の通り、ログメッセージです。今回は「警告!」というメッセージを表示するように指定しているため、messageには「警告!」が出力されるはずです。
では実際の出力を確認してみましょう。
WARNING:警告!
確かに、指定したフォーマット通りに出力できています。
フォーマットを指定しなかった場合の出力と見比べてみましょう。
WARNING:root:警告!
指定しなかった時にはrootが含まれており、出力結果が変わっていることがわかりますね。
なお、サンプルコードは別のモジュールを想定しているため、毎回importとgetLoggerを記述しています。同じモジュールであれば一度記述すればよいので注意しましょう。
色々なフォーマット
次は、どんなフォーマットを指定できるのか見ていきましょう。
asctimeを使えば時刻を表示できます。
import logging logging.basicConfig(format='%(asctime)s:%(message)s') logger = logging.getLogger(__name__) logging.warning('メッセージ')
2018-09-11 19:20:52,390:メッセージ
funcNameを使えばloggingを呼び出している関数名を表示できます。
import logging logging.basicConfig(format='%(funcName)s:%(message)s') logger = logging.getLogger(__name__) logging.warning('メッセージ')
<module>:メッセージ
せっかくなので関数を作ってもう一度実行してみましょう。
import logging def showlog(): logging.basicConfig(format='%(funcName)s:%(message)s') logger = logging.getLogger(__name__) logging.warning('メッセージ') if __name__ == '__main__': showlog()
showlog:メッセージ
showlog()という関数名が正しく表示されていますね!
その他にも
loggingが呼び出された行番号がわかる%(lineno)d、loggingが呼び出されたファイルのフルパスがわかる%(pathname)s、プロセスIDがわかる%(process)dなんてものもあります。
もっとlogging formatを便利に使おう
ここまで、フォーマットを指定するログメッセージを見てきました。
次は、loggingをさらに便利に使う方法について説明していきます。
ログレベルとは?
今まで
logging.warning('メッセージ')
でログメッセージを出力していました。
これは前述の通り、WARNINGというログレベルでログメッセージを出力しています。
今度は他のレベルでログメッセージを出力できるか見てみましょう。
import logging logging.basicConfig(format='%(levelname)s:%(levelno)s') logger = logging.getLogger(__name__) logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical')
WARNING:30 ERROR:40 CRITICAL:50
DEBUGが最も重要度が低く、CRITICALが最も重要度が高いです。
デフォルトのレベルはWARNINGに設定されているため、WARNINGよりも重要度が高いログメッセージだけが出力されています。
次はレベルをWARNINGからDEBUGに変更して、同じようにログメッセージを表示してみましょう。
import logging logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(levelno)s') logger = logging.getLogger(__name__) logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical')
formatと同じくbasicConfig()でlevelをDEBUGに変更しました。早速、出力を見てみましょう。
DEBUG:10 INFO:20 WARNING:30 ERROR:40 CRITICAL:50
DEBUGが最も重要度が低いため、すべてのログメッセージが出力されていますね!
このようにログレベルによって表示の有無を簡単に設定できるのです。
ログ出力を無効化する
続いて、ログ出力を無効化してみましょう。
import logging logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(levelno)s') logger = logging.getLogger(__name__) logging.disable(logging.WARNING) logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical')
ERROR:40 CRITICAL:50
logging.disable()でWARNINGを指定しました。これによって指定したレベル以下のログメッセージはすべて抑制されます。
そのため今回のコードではWARNING以下のレベル(WARNING, INFO, DEBUG)がすべて無効化されました。
print文とは違い、ログメッセージの無効化を使えばたった一行でログメッセージを見やすくできるのです。
ログをファイルに出力する
今までは、画面上にログメッセージを表示してきました。しかし、ログメッセージはファイルに書き出すこともできるのです。
import logging logging.basicConfig(filename='log.txt', format='%(levelname)s:%(levelno)s') logger = logging.getLogger(__name__) logging.warning('warning')
今までと同様に、WARNINGレベルのログメッセージを表示します。ただし今回はlog.txtというファイルにログメッセージを保存しています。
画面上ではなくファイル上にログを書き出せば、ログメッセージで画面を埋めることなく後で保存されたログメッセージを読めるため、非常に便利です。
その他のloggingの使い方については以下の記事で詳しく書いています。ぜひご参照ください。
まとめ
今回は、loggingモジュールのbasicConfig()関数を使うことによって、ログメッセージの表示を変更できることを紹介しました。
loggingはプログラムの動作確認やデバッグで役立ちます。
ぜひマスターしてログを簡単にとれるようになりましょう!