Saya mencetak pesan pengecualian Python ke file log dengan logging.error
:
import logging
try:
1/0
except ZeroDivisionError as e:
logging.error(e) # ERROR:root:division by zero
Apakah mungkin untuk mencetak informasi yang lebih terperinci tentang pengecualian dan kode yang dihasilkannya daripada hanya string pengecualian? Hal-hal seperti nomor baris atau jejak tumpukan akan menjadi hal yang hebat.
python
exception
logging
exception-handling
mungkin di pantai
sumber
sumber
exception
Metode hanya panggilanerror(message, exc_info=1)
. Segera setelah Anda melewatiexc_info
salah satu metode logging dari konteks pengecualian, Anda akan mendapatkan traceback.sys.excepthook
(lihat di sini ) untuk menghindari keharusan membungkus semua kode Anda di coba / kecuali.except Exception:
karena Anda tidak menggunakane
cara apa pun;)e
ketika mencoba untuk debug kode Anda secara interaktif. :) Inilah sebabnya saya selalu memasukkannya.raise
di akhirexcept
ruang lingkup. Kalau tidak, berlari akan berlanjut seolah semuanya baik-baik saja.Satu hal
logging.exception
yang menyenangkan tentang jawaban SiggyF ini tidak muncul adalah bahwa Anda dapat mengirimkan pesan yang sewenang-wenang, dan pencatatan log masih akan menampilkan traceback penuh dengan semua detail pengecualian:Dengan perilaku pencatatan default (dalam versi terbaru) untuk kesalahan pencetakan saja
sys.stderr
, tampilannya seperti ini:sumber
''
jika Anda benar-benar tidak ingin mengetik pesan ... fungsi tidak dapat dipanggil tanpa setidaknya satu argumen, jadi Anda harus memberikan sesuatu.Menggunakan
exc_info
opsi mungkin lebih baik, untuk memungkinkan Anda memilih tingkat kesalahan (jika Anda menggunakannyaexception
, itu akan selalu berada dierror
tingkat):sumber
logging.fatal
metode di perpustakaan logging? Saya hanya melihatcritical
.critical
, sama sepertiwarn
untukwarning
.Mengutip
Sekarang,
traceback
bisa digunakan di sini.Gunakan dalam Python 2 :
Gunakan dalam Python 3 :
sumber
ex_traceback
dariex.__traceback__
bawah Python 3, tetapiex_traceback
darisys.exc_info()
bawah Python 2.Jika Anda menggunakan log polos - semua catatan log Anda harus sesuai aturan ini:
one record = one line
. Mengikuti aturan ini, Anda dapat menggunakangrep
dan alat lain untuk memproses file log Anda.Tetapi informasi traceback bersifat multi-line. Jadi jawaban saya adalah versi diperpanjang dari solusi yang diusulkan oleh zangw di atas di utas ini. Masalahnya adalah bahwa garis traceback bisa ada
\n
di dalam, jadi kita perlu melakukan pekerjaan ekstra untuk menyingkirkan ujung garis ini:Setelah itu (ketika Anda akan menganalisis log), Anda dapat menyalin / menempelkan baris traceback yang diperlukan dari file log Anda dan melakukan ini:
Keuntungan!
sumber
Jawaban ini dibangun dari yang terbaik di atas.
Di sebagian besar aplikasi, Anda tidak akan memanggil logging.exception (e) secara langsung. Kemungkinan besar Anda telah menetapkan logger khusus untuk aplikasi atau modul Anda seperti ini:
Dalam hal ini, cukup gunakan logger untuk memanggil pengecualian (e) seperti ini:
sumber
Anda dapat mencatat jejak stack tanpa terkecuali.
https://docs.python.org/3/library/logging.html#logging.Logger.debug
Contoh:
sumber
Sedikit perawatan dekorator (sangat longgar terinspirasi oleh Mungkin monad dan mengangkat). Anda dapat menghapus anotasi tipe Python 3.6 dengan aman dan menggunakan gaya pemformatan pesan yang lebih lama.
fallible.py
Demo:
Anda juga dapat memodifikasi solusi ini untuk mengembalikan sesuatu yang sedikit lebih bermakna daripada
None
dariexcept
bagian (atau bahkan membuat solusi generik, dengan menentukan nilai pengembalian ini dalamfallible
argumennya).sumber
Dalam modul logging Anda (jika modul khusus) aktifkan stack_info.
sumber
Jika Anda dapat mengatasi ketergantungan tambahan kemudian menggunakan twisted.log, Anda tidak perlu secara eksplisit mencatat kesalahan dan juga mengembalikan seluruh traceback dan waktu ke file atau streaming.
sumber
twisted
rekomendasi yang bagus, tetapi jawaban ini tidak banyak berkontribusi. Ia tidak mengatakan bagaimana cara menggunakannyatwisted.log
, atau kelebihan apa yang dimilikinya daripadalogging
modul dari pustaka standar, atau menjelaskan apa yang dimaksud dengan "Anda tidak harus secara eksplisit mencatat kesalahan" .Cara bersih untuk melakukannya adalah menggunakan
format_exc()
dan kemudian mengurai output untuk mendapatkan bagian yang relevan:Salam
sumber
.split('\n')[-2]
dilakukan hanyalah membuang nomor baris dan traceback dari hasilformat_exc()
- informasi berguna yang biasanya Anda inginkan! Terlebih lagi, bahkan tidak melakukan pekerjaan yang baik itu ; jika pesan pengecualian Anda berisi baris baru, maka pendekatan ini hanya akan mencetak baris terakhir dari pesan pengecualian - yang berarti bahwa Anda kehilangan kelas pengecualian dan sebagian besar pesan pengecualian di atas kehilangan traceback. -1.