先日 python の logging について書きましたが、
そういえば、ログにスタックトレースを出力する方法について書いてなかったな
と思ったので、今回記事にしてみます。
ちなみに、logging の基本的な使い方については以下の記事をご参考ください。
コード作成時には予想もしていなかった例外エラーが発生する、なんてことは
ザラにあると思いますので、そういったときに備える意味でも
スタックトレースを出力できるようにしておくと良いです。
StackTrace(スタックトレース)とは
IT分野での StackTrace(スタックトレース)とは、「プログラムが動作する中で
どのような処理がどの順番で呼び出されて実行されたのかを記録したもの」のことです。
(似たような言葉に TraceBack があり、こちらは、「プログラム動作中に不具合やエラーが発生した際、
その原因解明のために時系列順に処理をさかのぼって調査していくこと」を指します。)
予想していなかったエラーが発生した際には、ただログを見るだけではエラーの原因を
特定することは難しいですが、このスタックトレースをしっかりと解析することで、
プログラム中のどこで処理が止まり、何が悪さをしているのかを特定することが容易になります。
Python では、プログラム実行中に例外エラーが発生すると、このスタックトレースが画面上に表示されます。
例えば、Requets という Python のモジュールを使用してインターネット上のサイトへ
アクセスしようとした際に、上手くインターネット接続できなかった場合、以下のような
スタックトレースが表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Traceback (most recent call last): File "site-packages\requests\adapters.py", line 449, in send File "site-packages\urllib3\connectionpool.py", line 638, in urlopen File "site-packages\urllib3\util\retry.py", line 367, in increment File "site-packages\urllib3\packages\six.py", line 685, in reraise File "site-packages\urllib3\connectionpool.py", line 600, in urlopen File "site-packages\urllib3\connectionpool.py", line 343, in _make_request File "site-packages\urllib3\connectionpool.py", line 839, in _validate_conn File "site-packages\urllib3\connection.py", line 344, in connect File "site-packages\urllib3\util\ssl_.py", line 344, in ssl_wrap_socket File "ssl.py", line 412, in wrap_socket File "ssl.py", line 853, in _create File "ssl.py", line 1117, in do_handshake urllib3.exceptions.ProtocolError: ('Connection aborted.', OSError(0, 'Error')) |
上記のログを見ると、どのモジュールの何行目がどのタイミングで呼び出されたのか、
というのが順番に書かれていることがわかりますね。
他、スタックトレースについては以下のサイトが分かりやすく解説されています。
併せて参考にしてみてください。
・「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
|
|
ログファイルへStackTraceを出力するサンプルコード
logging モジュールを使用してスタックトレースをログ出力するサンプルコードを紹介します。
logging の基本的な設定を行ったうえで、
以下のように、例外処理が発生しそうなところに try 文と logger.exception を挿入します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import logging # logger の作成 logger = logging.getLogger(__name__) # コンソール画面用ハンドラー設定 consoleHandler = logging.StreamHandler() # logger と コンソール用ハンドラーの関連付け logger.addHandler(consoleHandler) try: 【例外が発生しそうな処理】 except Exception as e: logger.exception("【任意のメッセージ】") |
注意点としては、ただ logger.error() で記載しただけでは、
エラーメッセージは出力されても、スタックトレースは出力されない ということです。
もし logger.error() を使用してスタックトレースを出力させたい場合は、
以下のように記述することで可能になるようです。
僕は logger.exception() の方を使っています。コードがスッキリ見えるので^^
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import logging # logger の作成 logger = logging.getLogger(__name__) # コンソール画面用ハンドラー設定 consoleHandler = logging.StreamHandler() # logger と コンソール用ハンドラーの関連付け logger.addHandler(consoleHandler) try: 【例外が発生しそうな処理】 except Exception as e: logging.error(【任意のメッセージ】, exc_info=True) |
さいごに
スタックトレースを実装するにあたり、以下のサイトを参考にさせていただきました。
ありがとうございました。
・loggingで例外情報を出力する
・【Python】loggingのerror()とexception()の違い
トレースバック出力については、python モジュールの Traceback というものもあるようですが、
そちらも後々勉強してみようと思います。
ではでは。
コメント