error()とexception()の違いがわからない
exceptionの詳細情報までloggerに入れたい
こんにちは!ライターの遠藤です。今回の記事では、loggerを使ってログを取得する方法やexceptionが起きた時のログの取り方について、とりわけexception()について解説致します。
この記事はこんな人のために書きました
- loggerの使い方やレベル設定について詳しく知りたい
- 例外発生時のログの取得方法について詳しく知りたい
本記事を読んでいただければ、loggingの基礎とexception()ログについて理解する事ができます。
本記事を読む前に、Pythonがどんなプログラミング言語なのかをおさらいしておきたい人は次の記事を参考にしてください。
→ Pythonとは?特徴やできること、活用例をわかりやすく簡単に解説
なお、その他のPythonの記事についてはこちらにまとめています。
Pythonのloggerの使い方
まずはじめに、loggingについて簡単に説明致します。
loggingとは、処理の過程をログファイルに記録していく事を言います。ログを取る事で、バグが発生した時の調査などにとても役立ちます。
また、pythonではloggingという標準ライブラリにあるモジュールを使うことで、loggingを行う事ができます。
実際の使い方は以下のようになります。
import logging # ログの出力名を設定 logger = logging.getLogger('LoggingTest') ''' ログをファイルに出力する場合は以下を記述 ''' fh = logging.FileHandler('loggingtest.log') #ファイル名を設定 logger.addHandler(fh) ''' ログをコンソールに出力する場合は以下を記述 ''' sh = logging.StreamHandler() logger.addHandler(sh) ''' loggerに記録 ''' logger.log(20, 'info') logger.log(30, 'warning') logger.log(100, 'test') logger.info('info') logger.warning('warning') logger.error('error') logger.exception('exception')
実行結果:
warning test warning error exception None
上記のようにして記録していきます。
ポイントは以下になります。
- loggingをインポート
- logging.getLogger()で出力名を設定し、ロガーを生成
- ログをファイルに出力する為にはFileHandler()を呼び出す
- ログをコンソールに出力する為にはStreamHandler()を呼び出す
- ログに記録する
「5. ログに記録する」の際ですが、log()やinfo()などの関数を呼んでいます。
これについて次の章で説明致します。
ロギングレベルの設定方法
先述の通り、ログに記録する際、log()やinfo()などを呼んでいますね。
いずれもログに記録する処理を行なっているのですが、ここでポイントとなるのはロギングレベルという、ログの等級です。
順番が前後しますが、log()の第2引数に入力しているのがログのメッセージです。これがログファイルに記録されます。
そして第1引数がロギングレベルです。loggingでは、記録したい情報を以下のように等級分けしています。
等級 | 設定値 | 内容 |
---|---|---|
DEBUG | 0 | おもに問題を診断するときにのみ確認したい情報の記録 |
INFO | 10 | 想定された通りになっているかを確認する為の記録 |
WARNING | 20 | 想定外のことが起こった場合、または問題が起こりそうな異常が見られる場合の記録 |
ERROR | 30 | WARNINGよりも重大な問題で、ある機能そのものがを実行できない場合などを記録 |
CRITICAL | 40 | プログラム自体が実行を続けられない場合の重大なエラーを記録 |
log()の第1引数では、このログレベルを入力しています。ここで、前章の実行結果をご確認ください。
コード上では「logger.log(20, ‘info’)」と記録する呼び出しがあるにもかかわらず、実行結果には出力されていません。これは、ロギングレベルによってフィルタリングされたものが出力されている為です。
logger()では、デフォルトでWARKINGより上(20以上)のロギングレベルのログを出力するようになっています。このフィルターを変更するには以下の行を入れます。
import logging # ログの出力名を設定 logger = logging.getLogger('LoggingTest') # ロギングレベルの設定 logger.setLevel(10) fh = logging.FileHandler('loggingtest.log') logger.addHandler(fh) sh = logging.StreamHandler() logger.addHandler(sh) logger.log(20, 'info') logger.log(30, 'warning') logger.log(100, 'test') logger.info('info') logger.warning('warning') logger.error('error') logger.exception('exception')
上記のようにしてsetLevel()をセットする事で、出力するログレベルを設定できます。
これを実行すると
info warning test info warning error exception None
“info”も出力されました。
なお、log()以外のinfo()やwarning()などは、ロギングレベルを引数に入力しなくても、対応したロギングレベルで自動に記録できます。
例外発生時のログの取り方
ログの取り方がわかった所で、例外が発生した時にそれをキャッチし、ログに出力する方法を紹介します。
import math import logging # ログの出力名を設定 logger = logging.getLogger('LoggingTest') fh = logging.FileHandler('loggingtest.log') logger.addHandler(fh) sh = logging.StreamHandler() logger.addHandler(sh) try: math.log(-1) except ValueError as err: logger.exception('Raise Exception: %s', err)
例外が発生しそうな箇所にtry-exceptを入れ、exceptの行にexception()を入れます。このようにする事で、例外発生時のログを記録する事ができます。
実行結果:
Raise Exception: math domain error Traceback (most recent call last): File "test.py", line 16, in <module> math.log(-1) ValueError: math domain error
exception()はerror()じゃだめなの?
ここで「exception()はerror()にしちゃだめなの?」と疑問に思われている方もいらっしゃるかと思います。結論から言うと、基本的には例外発生時のエラーはexception()にした方が良いです。
理由としては、exception()にすればtracebackをログに記録できる為です。error()では任意に設定したメッセージを記録する事しかできず、例外情報の詳細がわからない点がexception()と違います。
特別な理由がない限り、例外をキャッチした場合はexception()を呼んでエラー詳細も記録するようにしましょう。
まとめ
この記事では、loggerの使い方や例外発生時のログの取り方などについて紹介致しました。
loggerの使い方をしっかり理解すると、バグ調査が簡単になったり、テスターの方へ依頼してログを取得してもらうといった作業分担も可能になります。
ぜひここでloggerの使い方の基礎を覚えて、活用してみてください。