Bagaimana saya bisa mencatat kesalahan Python saya?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
Bagaimana saya bisa mencatat kesalahan Python saya?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
Gunakan logging.exception
dari dalam except:
pawang / blok untuk mencatat pengecualian saat ini bersama dengan informasi jejak, yang diawali dengan pesan.
import logging
LOG_FILENAME = '/tmp/logging_example.out'
logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)
logging.debug('This message should go to the log file')
try:
run_my_stuff()
except:
logging.exception('Got exception on main handler')
raise
Sekarang melihat file log, /tmp/logging_example.out
:
DEBUG:root:This message should go to the log file
ERROR:root:Got exception on main handler
Traceback (most recent call last):
File "/tmp/teste.py", line 9, in <module>
run_my_stuff()
NameError: name 'run_my_stuff' is not defined
logger = logging.getLogger('yourlogger')
Anda harus menulislogger.exception('...')
agar ini berfungsi ...Gunakan
exc_info
opsi mungkin lebih baik, tetap judul peringatan atau kesalahan:sumber
exc_info=
disebut kwarg; Terima kasih!logging.exception
Pekerjaan saya baru-baru ini menugasi saya untuk mencatat semua traceback / pengecualian dari aplikasi kami. Saya mencoba berbagai teknik yang telah diposting orang lain secara online seperti yang di atas tetapi memilih pendekatan yang berbeda. Mengesampingkan
traceback.print_exception
.Saya punya tulisan di http://www.bbarrows.com/ Itu akan jauh lebih mudah dibaca tetapi saya akan menempelkannya di sini juga.
Ketika ditugaskan untuk mencatat semua pengecualian yang mungkin ditemui oleh perangkat lunak kami di alam liar, saya mencoba sejumlah teknik berbeda untuk mencatat traceback python pengecualian kami. Pada awalnya saya berpikir bahwa sistem hook python pengecualian, sys.excepthook akan menjadi tempat yang sempurna untuk memasukkan kode logging. Saya mencoba sesuatu yang mirip dengan:
Ini berfungsi untuk utas utama tetapi saya segera menemukan bahwa sys.excepthook saya tidak akan ada di utas baru pun memulai proses saya. Ini adalah masalah besar karena kebanyakan semuanya terjadi di utas dalam proyek ini.
Setelah googling dan membaca banyak dokumentasi, informasi paling bermanfaat yang saya temukan adalah dari pelacak Isu Python.
Posting pertama di utas menunjukkan contoh kerja dari
sys.excepthook
TIDAK yang bertahan di utas (seperti yang ditunjukkan di bawah). Ternyata ini perilaku yang diharapkan.Pesan pada utas Python Issue ini benar-benar menghasilkan 2 peretasan yang disarankan. Entah subkelas
Thread
dan bungkus metode jalankan dalam percobaan kami sendiri kecuali blok untuk menangkap dan mencatat pengecualian atau patch monyetthreading.Thread.run
untuk berjalan dalam percobaan Anda sendiri kecuali memblokir dan mencatat pengecualian.Metode pertama dari subclassing
Thread
bagi saya tampaknya kurang elegan dalam kode Anda karena Anda harus mengimpor dan menggunakanThread
kelas kustom di mana pun Anda ingin memiliki thread logging. Ini akhirnya menjadi masalah karena saya harus mencari seluruh basis kode kami dan mengganti semua normalThreads
dengan kebiasaan iniThread
. Namun, jelas apa yangThread
sedang dilakukan dan akan lebih mudah bagi seseorang untuk mendiagnosis dan men-debug jika ada yang salah dengan kode logging kustom. Thread custome logging mungkin terlihat seperti ini:Metode kedua dari patch monyet
threading.Thread.run
bagus karena saya bisa menjalankannya sekali saja dan memasukkan__main__
kode logging saya di semua pengecualian. Menambal monyet bisa mengganggu untuk debug meskipun karena mengubah fungsionalitas yang diharapkan dari sesuatu. Tambalan yang disarankan dari pelacak Isu Python adalah:Tidak sampai saya mulai menguji pengecualian logging saya, saya menyadari bahwa saya salah melakukan semuanya.
Untuk menguji saya telah menempatkan a
di suatu tempat dalam kode saya. Namun, membungkus metode yang disebut metode ini adalah percobaan kecuali blok yang mencetak traceback dan menelan pengecualian. Ini sangat menyebalkan karena saya melihat traceback membawa cetakan ke STDOUT tetapi tidak dicatat. Saya kemudian memutuskan bahwa metode yang jauh lebih mudah untuk mencatat tracebacks adalah dengan menambal metode yang semua kode python gunakan untuk mencetak tracebacks sendiri, traceback.print_exception. Saya berakhir dengan sesuatu yang mirip dengan yang berikut:
Kode ini menulis traceback ke String Buffer dan mencatatnya untuk mencatat ERROR. Saya memiliki penangan logging kustom mengatur logger 'customLogger' yang mengambil log tingkat ERROR dan mengirim mereka pulang untuk analisis.
sumber
add_custom_print_exception
tampaknya tidak ada di situs yang Anda tautkan, dan alih-alih ada beberapa kode akhir yang sangat berbeda di sana. Mana yang akan Anda katakan lebih baik / lebih final dan mengapa? Terima kasih!logger.error(traceback.format_tb())
(atau format_exc () jika Anda menginginkan info pengecualian juga).Anda dapat mencatat semua pengecualian yang tidak tertangkap pada utas utama dengan menetapkan penangan
sys.excepthook
, mungkin menggunakanexc_info
parameter fungsi logging Python :Namun, jika program Anda menggunakan utas, maka perhatikan bahwa utas yang dibuat menggunakan tidak
threading.Thread
akan memicu ketika pengecualian tanpa tertangkap terjadi di dalamnya, seperti yang dicatat dalam Masalah 1230540 pada pelacak masalah Python. Beberapa peretasan telah disarankan di sana untuk mengatasi keterbatasan ini, seperti penambalan monyet untuk menimpa dengan metode alternatif yang membungkus sumber asli dalam sebuah blok dan panggilan dari dalam blok. Atau, Anda bisa hanya secara manual membungkus entry point untuk setiap benang Anda di / diri sendiri.sys.excepthook
Thread.__init__
self.run
run
try
sys.excepthook
except
try
except
sumber
Pesan pengecualian yang tidak tertangkap masuk ke STDERR, jadi alih-alih menerapkan logging dengan Python sendiri, Anda bisa mengirim STDERR ke file menggunakan shell apa pun yang Anda gunakan untuk menjalankan skrip Python. Dalam skrip Bash, Anda bisa melakukan ini dengan pengalihan output, seperti yang dijelaskan dalam panduan BASH .
Contohnya
Tambahkan kesalahan ke file, output lain ke terminal:
Timpa file dengan output STDOUT dan STDERR yang disisipkan:
sumber
Apa yang saya cari:
Lihat:
sumber
Anda bisa mendapatkan traceback menggunakan logger, di tingkat mana pun (DEBUG, INFO, ...). Perhatikan bahwa menggunakan
logging.exception
, levelnya ERROR.EDIT:
Ini juga berfungsi (menggunakan python 3.6)
sumber
Ini adalah versi yang menggunakan sys.excepthook
sumber
{traceback.format_exc()}
bukan{traceback.format_tb(stack)}
?mungkin tidak bergaya, tetapi lebih mudah:
sumber
Inilah contoh sederhana yang diambil dari dokumentasi python 2.6 :
sumber