目次
語彙
レベル
ログにつける表示の優先順位。レベルについての解説参照。
ロガー
ログを分割してまとめ上げるインスタンス。ロガーについての解説参照。
ハンドラー
ログを表示するターミナルやファイルなどの動態を記述するインスタンス。ロガーについての解説参照。
ファイルハンドラー
テキストファイルなどの形でログを出力するためのハンドラー。ロガーについての解説参照。
ストリームハンドラー
ターミナルにログを表示するためのハンドラー。ロガーについての解説参照。
レベル
タスク | 最適なレベル |
---|---|
問題を診断するときのみに関心のある詳細な情報 | logging.DEBUG |
想定通りのことが起こったことの確認 | logging.INFO |
想定外のことが起こった、もしくは起こりそうなことの警告 | logging.WARNING |
より重大な問題によって、ソフトウェアがある機能を実行できないことの表示 | logging.ERROR |
プログラム自体が実行できないような重大なエラー | logging.CRITICAL |
デフォルトのレベルは WARNING です。つまり特段設定をしなければ WARNING, ERROR, CRITICAL のレベルのログが出力されます。
ロガー
ログの機能は基本的にロガーというインスタンスを使って実装するのが望ましいとされています。というのは、ログを確認するときに用途別などカテゴライズができるからです。その有用性などについてはこちらのサイトで力説されていますので、ぜひ参考になさってください。
ログ出力のための print と import logging はやめてほしい
ではどのようにロガーを使えばいいか。まずはこちらのコードをご覧ください。
import logging
# declaring the logger
logger = logging.getLogger("logger1")
logger.setLevel(logging.DEBUG)
# getting stream handler (written on the terminal)
handler_s = logging.StreamHandler()
handler_s.setLevel(logging.DEBUG)
logger.addHandler(handler_s)
# getting file handler (written on the file)
handler_f = logging.FileHandler('log.txt')
handler_f.setLevel(logging.INFO)
logger.addHandler(handler_f)
logger.debug('DEBUG')
logger.warning('WARNING')
terminal
DEBUG
WARNING
log.txt
WARNING
基本の表し方はこの通りです。
まずロガー本体を宣言します。getLogger の引数がログを表示して区別するときに確認できるロガーの名前となり、名前を logger1 としました。「でも logger1 なんて他にはどこにも出てきてないじゃん」となった方は、もう少し待っててください。ちゃんと説明します。
その次の setLevel はロガーが受け付けるログの最低レベルを設定しています。ここでは「DEBUG 以上(つまり全部)のログを記録しておきますよ」ということ。
その次が stream handler の設定です。コードの実行途中にターミナルで表示するログですね。setLevel でターミナルに表示するレベルの下限を設定します。addHandler でロガーに適用です。
その後に file handler を設定します。別ファイルにログをまとめて書き出すものです。今回は log.txt というファイルに書き出します。もしその名前のファイルが存在しなければ新規作成します。残りは stream handler とほぼ同じですね。レベルだけは INFO 以上、つまり DEBUG を表示しないようにしています。ターミナルとファイルのそれぞれの結果をよく照らし合わせてください。
これだけだとロガーの威力はほとんど感じられないでしょうから、もう一つ例を題しておきます。ちょいと長くなりますがその点はご勘弁を。
import logging
# declaring the loggers
logger1 = logging.getLogger("Logger1")
logger1.setLevel(logging.DEBUG)
logger2 = logging.getLogger("Logger2")
logger2.setLevel(logging.ERROR)
# getting the stream handler (written on the terminal)
handler_s = logging.StreamHandler()
handler_s.setLevel(logging.INFO)
handler_s.setFormatter(logging.Formatter('%(name)s - %(message)s'))
logger1.addHandler(handler_s)
logger2.addHandler(handler_s)
# getting the file handler (written on the file)
handler_f = logging.FileHandler('log.txt')
handler_f.setLevel(logging.DEBUG)
handler_f.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s'))
logger1.addHandler(handler_f)
logger2.addHandler(handler_f)
logger1.debug('DEBUG')
logger1.warning('WARNING')
logger2.warning('WARNING')
logger2.critical('CRITICAL')
terminal
Logger1 - WARNING
Logger2 - CRITICAL
log.txt
2020-12-23 21:59:17,560 - DEBUG - Logger1 - DEBUG
2020-12-23 21:59:17,560 - WARNING - Logger1 - WARNING
2020-12-23 21:59:17,560 - CRITICAL - Logger2 - CRITICAL
こうしてロガー別に名前を変えたりレベルを変えたりして、ログの整理を用意にすることができるようになります。