はじめに
loggingのloggerを使ってログ出力をする際に、発生した場所を把握するために位置情報も一緒に出力したい時がある。有り体に言えば、tracebackが欲しい。
このtracebackをログに含める時にどうすると良いかという話。
愚直な方法
もちろん自分でtracebackをログに付加してあげれば良いという話もある。以下のように。
import logging
import traceback
logger = logging.getLogger("sample")
def foo():
bar()
def bar():
logger.info("bar")
logger.info("tb: %s", "".join(traceback.format_stack()))
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
foo()
一応tracebackは表示される。
INFO:sample:bar
INFO:sample:tb: File "qr_64852sBQ.py", line 18, in <module>
foo()
File "qr_64852sBQ.py", line 8, in foo
bar()
File "qr_64852sBQ.py", line 13, in bar
logger.info("tb: %s", "".join(traceback.format_stack()))
とは言えわざわざ自分でtracebackを取ってくると言うのは面倒ではあるし。そもそもログ出力のためだけにpythonの知識(import traceback
)を要求するのはおかしい。
stack_info
実際、上のようにtracebackを自分で付与する必要はなく、loggerでログ出力する時に stack_info=True
をつけてあげれば良い。
--- 00sample.py 2017-07-13 08:06:10.000000000 +0900
+++ 01sample.py 2017-07-13 08:09:06.000000000 +0900
@@ -1,6 +1,5 @@
# -*- coding:utf-8 -*-
import logging
-import traceback
logger = logging.getLogger("sample")
@@ -9,8 +8,7 @@
def bar():
- logger.info("bar")
- logger.info("tb: %s", "".join(traceback.format_stack()))
+ logger.info("bar", stack_info=True)
実行してみると Stack (most recent call last)
以降にtracebackが表示される。
INFO:sample:bar
Stack (most recent call last):
File "qr_64852GWc.py", line 16, in <module>
foo()
File "qr_64852GWc.py", line 7, in foo
bar()
File "qr_64852GWc.py", line 11, in bar
logger.info("bar", stack_info=True)
exc_info
ログの出力時の位置ではなく例外の発生位置のtracebackを表示したいこともある。例えば logger.exceptipn()
などを使った場合と同様の形式。
これには stack_info
の代わりに exc_info
を渡せば良い。
import logging
logger = logging.getLogger("sample")
def foo():
bar()
def bar():
logger.info("bar")
1 / 0
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
try:
foo()
except:
logger.info("hmm", exc_info=True)
zero division errorの発生位置のtracebackは例外オブジェクトから抽出され自動で併記してくれるようになる。
INFO:sample:bar
INFO:sample:hmm
Traceback (most recent call last):
File "qr_64852t0u.py", line 18, in <module>
foo()
File "qr_64852t0u.py", line 7, in foo
bar()
File "qr_64852t0u.py", line 12, in bar
1 / 0
ZeroDivisionError: division by zero