Jak mechmind odpowiedział ślad stos składa się wyłącznie z klatek pomiędzy miejscem, gdzie wyjątek został podniesiony i witryny bloku try
. Jeśli potrzebujesz pełnego śledzenia stosu, najwyraźniej masz pecha.
Poza tym oczywiście możliwe jest wyodrębnienie wpisów stosu z najwyższego poziomu do bieżącej klatki - traceback.extract_stack
zarządza nią dobrze. Problem polega na tym, że informacje uzyskane przez traceback.extract_stack
pochodzą z bezpośredniej inspekcji ramek stosów bez tworzenia obiektu śledzenia w dowolnym punkcie, a interfejs API logging
wymaga, aby obiekt śledzenia był odpowiedzialny za wpływanie na wynik śledzenia.
szczęście logging
nie wymaga rzeczywisty Traceback obiekt, wymaga on obiekt, który może przejść do procedury formatowania modułu traceback
. traceback
to też nie obchodzi - wykorzystuje tylko dwa atrybuty traceback, ramkę i numer linii. Powinno być zatem możliwe stworzenie połączonej listy obiektów faux-traceback z kaczkami i przekazywanie jej jako traceback.
import sys
class FauxTb(object):
def __init__(self, tb_frame, tb_lineno, tb_next):
self.tb_frame = tb_frame
self.tb_lineno = tb_lineno
self.tb_next = tb_next
def current_stack(skip=0):
try: 1/0
except ZeroDivisionError:
f = sys.exc_info()[2].tb_frame
for i in xrange(skip + 2):
f = f.f_back
lst = []
while f is not None:
lst.append((f, f.f_lineno))
f = f.f_back
return lst
def extend_traceback(tb, stack):
"""Extend traceback with stack info."""
head = tb
for tb_frame, tb_lineno in stack:
head = FauxTb(tb_frame, tb_lineno, head)
return head
def full_exc_info():
"""Like sys.exc_info, but includes the full traceback."""
t, v, tb = sys.exc_info()
full_tb = extend_traceback(tb, current_stack(1))
return t, v, full_tb
Z tych funkcji w miejscu, kod wymaga jedynie trywialną modyfikacji:
import logging
def func():
try:
raise Exception('Dummy')
except:
logging.error("Something awful happened!", exc_info=full_exc_info())
def func2():
func()
func2()
... dać oczekiwany wynik:
ERROR:root:Something awful happened!
Traceback (most recent call last):
File "a.py", line 52, in <module>
func2()
File "a.py", line 49, in func2
func()
File "a.py", line 43, in func
raise Exception('Dummy')
Exception: Dummy
Należy pamiętać, że faux-traceback obiekty są w pełni użyteczne do wyświetlania zmiennych lokalnych w introspekcji lub jako argument do pdb.post_mortem()
- ponieważ zawierają odniesienia do rzeczywistych ramek stosów.
możliwy duplikat [Jak zapisać wartości traceback/sys.exc \ _info() w zmiennej?] (Http://stackoverflow.com/questions/8238360/how-to-save-traceback-sys-exc- info-values-in-a-variable) – Nathan
@Nathan, przeczytaj ponownie uważnie to pytanie. ** Pełny ** traceback jest potrzebny. – warvariuc
Zobacz [Generowanie śledzenia stosu dla wyjątków w Pythonie.] (Http://blog.dscpl.com.au/2015/03/generating-full-stack-traces-for.html) wpis na blogu Grahama Dupletona. –