[PYTHON] It is convenient to use stac_info and exc_info when you want to display traceback in log output by logging.

Introduction

When you want to output the location information together with the location information when you output the log using the logger of logging There is. To put it tangibly, I want a traceback. Talk about what to do when including this traceback in the log.

Stupid way

Of course, there is a story that you can add traceback to the log by yourself. As below.

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 is displayed for the time being.

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()))

However, it is troublesome to bother to fetch the traceback by yourself. It is strange to require knowledge of python (ʻimport traceback`) just for log output in the first place.

stack_info

In fact, you don't have to add traceback yourself as above, just add stack_info = True when logging with logger.

--- 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)

When I run it, traceback is displayed after Stack (most recent call last).

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

You may want to display the traceback of the exception occurrence position instead of the log output position. For example, the same format as when using logger.exceptipn (). You can do this by passing ʻexc_info instead of stack_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)

The traceback of the position where the zero division error occurs is extracted from the exception object and automatically written together.

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

Recommended Posts

It is convenient to use stac_info and exc_info when you want to display traceback in log output by logging.
When you want to use it as it is when using it with lambda memo
[Python] When you want to import and use your own package in the upper directory
[Python] When you want to use all variables in another file
When you run diff in python and want both returncode and output
It is convenient to use Icecream instead of print when debugging.
If you want to count words in Python, it's convenient to use Counter.
How to use is and == in Python
It is convenient to use Layers when putting a library on Lambda
It is more convenient to use csv-table when writing a table with python-sphinx
[OpenCV] When you want to check if it is read properly with imread
It is easy to execute SQL with Python and output the result in Excel
How to use Decorator in Django and how to make it
What is pip and how do you use it?
When you want to plt.save in a for statement
If you want to put an argument in the closure function and execute it later
If you want to use field names with hyphens when updating firestore data in python
Solution when you want to use cv_bridge with python3 (virtualenv)
Use aggdraw when you want to draw beautifully with pillow
When you want to use python2.x on modern Gentoo Linux
I want Sphinx to be convenient and used by everyone
Write a script in Shell and Python to notify you in Slack when the process is finished
Introduction to how to use Pytorch Lightning ~ Until you format your own model and output it to tensorboard ~
NameError: global name'dot_parser' is not defined and what to do when it comes up in python
[Subprocess] When you want to execute another Python program in Python code
Automatically acquire the operation log in the terminal when logging in to Linux
When it is troublesome to copy what you built with vue
When you want to print to standard output with print while testing with pytest
I want to create a pipfile and reflect it in docker
When you want to sort a multidimensional list by multiple lines
How to input a character string in Python and output it as it is or in the opposite direction.
What to do if you get the error RuntimeError: Python is not installed as a framework when trying to use matplitlib and pylab in Python 3.3