Python 104: cgitb (CGI Traceback)
⚠️ cgitb is deprecated since Python 3.11 and has been removed with Python 3.13!
Ich habe gerade mal wieder viel zu Lange über einen Python-Traceback gesessen, der mit einem annähernd nutzlosen TypeError: expected string or buffer
endete.
“Warum zum Henker gibt Python standarddmäßig nicht mehr Kontext aus?”
Bei meiner Recherche, wie mann z.B. für alle Stack-Frames eines Tracebacks zusätzliche die lokalen Variablen ausgiebt, bin ich dabei über das Standard-Python-Modul cgitb gestoßen, das genau das macht:
Zusätzlich zum Traceback gibt es für jedes Frame die lokalen Variablen und sogar noch den umliegenden Code aus, wahlweise als HTML oder text/plain
:
Python 2.7.9: /usr/bin/python
Wed Jun 6 22:37:55 2018
A problem occurred in a Python script. Here is the sequence of
function calls leading up to the error, in the order they occurred.
/root/ in ()
: integer division or modulo by zero
__class__ =
__delattr__ =
__dict__ = {}
__doc__ = ‚Second argument to a division or modulo operation was zero.‘
__format__ =
__getattribute__ =
__getitem__ =
__getslice__ =
__hash__ =
__init__ =
__new__ =
__reduce__ =
__reduce_ex__ =
__repr__ =
__setattr__ =
__setstate__ =
__sizeof__ =
__str__ =
__subclasshook__ =
__unicode__ =
args = (‚integer division or modulo by zero‘,)
message = ‚integer division or modulo by zero‘
The above is a description of an error in a Python program. Here is
the original traceback:
Traceback (most recent call last):
File „“, line 1, in
ZeroDivisionError: integer division or modulo by zero
/var/log/univention/tracebacks/tmpWrufjr.txt contains the description of this error.
Auf Wunsch schreibt es sogar diese Information in eine Datei und gibt statt dessen für den Benutzer eine lapidare Meldung folgender Art aus:
A problem occurred in a Python script.
/tmp/tmp7duTpd.txt contains the description of this error.
Das sollten wir IMHO standardmäßig in alle unsere Tools einbauen und sie nach /var/log/univention/tracebacks/
loggen lassen.
Das kann dann ein CRON-Job regelmäßig abgrasen und uns zukommen lassen.
python -c '__import__("cgitb").enable(1,None,5,"text");1/0'
python -c '__import__("cgitb").enable(1,"/tmp/",5,"text");1/0'
Canonical mach übrigens in Ubuntu etwas ähnliches in /etc/python2.7/sitecustomize.py
:
# install the apport exception handler if available
try:
import apport_python_hook
except ImportError:
pass
else:
apport_python_hook.install()
Wer also standardmäßig den erweiterten Traceback haben will, kann z.B. folgendes machen:
install -m 1777 -d /var/log/univention/tracebacks
cat >/usr/local/lib/python2.7/dist-packages/apport_python_hook.py <<__PY__
#!/usr/bin/python
import cgitb
def install():
cgitb.enable(1, "/var/log/univention/tracebacks", 5, "text")
__PY__
python -c '1 / 0'
Nur dummerweise führt /etc/univention/templates/files/etc/python2.7/sitecustomize.py.d/20utf8.py
ein reload(sys)
aus und macht es wieder Rückgänig.
Der Trick ist also, die beiden UCR-Fragmente noch zu vertauschen.