Bagaimana Anda mencatat kesalahan server di situs Django

175

Jadi, ketika bermain dengan pengembangan saya hanya dapat mengatur settings.DEBUGke Truedan jika terjadi kesalahan saya bisa melihatnya diformat dengan baik, dengan jejak tumpukan yang baik dan meminta informasi.

Tetapi pada jenis situs produksi saya lebih suka menggunakan DEBUG=Falsedan menunjukkan kepada pengunjung beberapa halaman kesalahan standar 500 dengan informasi yang sedang saya kerjakan untuk memperbaiki bug ini pada saat ini;)
Pada saat yang sama saya ingin memiliki beberapa cara untuk masuk semua informasi tersebut (susun jejak dan minta info) ke file di server saya - jadi saya bisa menampilkannya ke konsol saya dan menonton kesalahan gulir, email log ke saya setiap jam atau sesuatu seperti ini.

Solusi logging apa yang akan Anda rekomendasikan untuk situs django, yang akan memenuhi persyaratan sederhana itu? Saya memiliki aplikasi yang berjalan sebagai fcgiserver dan saya menggunakan server web apache sebagai frontend (walaupun berpikir untuk pergi ke lighttpd).

kender
sumber
sesuatu dari medan pertempuran: dlo.me/what-to-do-when-your-site-goes-viral
Cherian
2
Diperintahkan
Cherian
Tautan yang dibagikan Cherian sekarang mati. Jika Anda mencoba mencari Sentry, Anda kemungkinan akan menemukan materi untuk contoh resmi berbayar mereka, tetapi di sini adalah tautan untuk menyiapkan contoh yang di-host-sendiri: docs.sentry.io/server Juga, inilah repo yang saat ini dikelola: github .com / mendapat pemasukan / penjaga
lehiester

Jawaban:

103

Nah, kapan DEBUG = False, Django akan secara otomatis mengirimkan traceback penuh dari setiap kesalahan ke setiap orang yang tercantum dalam ADMINSpengaturan, yang membuat Anda mendapatkan pemberitahuan secara gratis. Jika Anda ingin lebih banyak kontrol berbutir halus, Anda dapat menulis dan menambahkan ke kelas pengaturan kelas middleware Anda yang mendefinisikan metode bernama process_exception(), yang akan memiliki akses ke pengecualian yang dimunculkan:

http://docs.djangoproject.com/en/dev/topics/http/middleware/#process-exception

process_exception()Metode Anda kemudian dapat melakukan apa pun jenis pencatatan yang Anda inginkan: menulis ke konsol, menulis ke file, dll., Dll.

Sunting: meskipun sedikit kurang berguna, Anda juga dapat mendengarkan got_request_exceptionsinyal, yang akan dikirim setiap kali ada pengecualian selama pemrosesan permintaan:

http://docs.djangoproject.com/en/dev/ref/signals/#got-request-exception

Namun, ini tidak memberi Anda akses ke objek pengecualian, sehingga metode middleware jauh lebih mudah digunakan.

James Bennett
sumber
7
Perhatikan bahwa menggunakan logging.exception('Some message')dengan modul logging standar python berfungsi dengan baik di pengendali utama untuk got_request_exception, jika semua yang Anda ingin lakukan adalah keluar dari tumpukan jejak. Dengan kata lain, traceback masih tersedia di got_request_exception.
TM.
Pengecualian yang diteruskan ke process_exception tampaknya tidak memiliki jejak tumpukan, apakah ada cara untuk mendapatkannya?
Nick BL
79

Django Sentry adalah cara yang baik untuk pergi, seperti yang telah disebutkan, tetapi ada sedikit pekerjaan yang terlibat dalam pengaturannya dengan benar (sebagai situs web terpisah). Jika Anda hanya ingin mencatat semuanya ke file teks sederhana di sini adalah konfigurasi logging untuk dimasukkan ke dalam file Andasettings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/var/log/django/myapp.log'
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'WARNING', # Or maybe INFO or DEBUG
            'propagate': False
        },
    },
}
EMP
sumber
Saya setuju, saya suka Sentry! Saya ingin memiliki port Net. (Sedang mengerjakan proyek .Net akhir-akhir ini).
Gromer
1
Salah ketik kecil kalau-kalau ada yang memotong & menempel: "propogate" alih-alih "propagate" di akhir.
user1228295
3
'include_html': TrueTIDAK hanya membuat email "lebih bagus"! Ini mencakup traceback penuh, termasuk nilai pengaturan dan variabel lokal. Sesuai dokumen, ini merupakan masalah keamanan: docs.djangoproject.com/en/1.8/topics/logging/…
Thomas
1
Saya ingin tahu apakah mail_admins handler (dan django.request logger) diperlukan karena Anda memiliki 'disable_existing_loggers': Salah dan hanya meniru penebangan django default dengan handler ini (dan logger). Saya akan memperbarui ketika saya sudah menguji.
DylanYoung
Harap perbarui jawaban ini. Dari django1.9 change-log: Konfigurasi logging default Django tidak lagi mendefinisikan 'django.request' dan 'django.security' logger.
narendra-choudhary
30

Jelas James benar, tetapi jika Anda ingin mencatat pengecualian di datastore, ada beberapa solusi open source yang sudah tersedia:

1) CrashLog adalah pilihan yang baik: http://code.google.com/p/django-crashlog/

2) Db-Log juga merupakan pilihan yang baik: http://code.google.com/p/django-db-log/

Apa perbedaan keduanya? Hampir tidak ada yang bisa saya lihat, jadi salah satu akan cukup.

Saya telah menggunakan keduanya dan mereka bekerja dengan baik.

montylounge
sumber
15

Beberapa waktu telah berlalu sejak pengiriman kode EMP yang paling membantu. Saya baru saja mengimplementasikannya, dan sementara meronta-ronta dengan beberapa opsi manage.py, untuk mencoba membasmi bug, saya mendapat peringatan penghentian akibat bahwa dengan versi Django saya saat ini (1,5.?) Filter require_debug_false sekarang dibutuhkan untuk penangan mail_admins.

Berikut adalah kode yang direvisi:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
         'require_debug_false': {
             '()': 'django.utils.log.RequireDebugFalse'
         }
     },
    'handlers': {
        # Include the default Django email handler for errors
        # This is what you'd get without configuring logging at all.
        'mail_admins': {
            'class': 'django.utils.log.AdminEmailHandler',
            'level': 'ERROR',
            'filters': ['require_debug_false'],
             # But the emails are plain text by default - HTML is nicer
            'include_html': True,
        },
        # Log to a text file that can be rotated by logrotate
        'logfile': {
            'class': 'logging.handlers.WatchedFileHandler',
            'filename': '/home/username/public_html/djangoprojectname/logfilename.log'
        },
    },
    'loggers': {
        # Again, default Django configuration to email unhandled exceptions
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
        # Might as well log any errors anywhere else in Django
        'django': {
            'handlers': ['logfile'],
            'level': 'ERROR',
            'propagate': False,
        },
        # Your own app - this assumes all your logger names start with "myapp."
        'myapp': {
            'handlers': ['logfile'],
            'level': 'DEBUG', # Or maybe INFO or WARNING
            'propagate': False
        },
    },
}
Mike O'Connor
sumber
Saya ingin tahu apakah mail_admins handler (dan django.request logger) diperlukan karena Anda memiliki 'disable_existing_loggers': Salah dan hanya meniru penebangan django default dengan handler ini (dan logger). Saya akan memperbarui ketika saya sudah menguji.
DylanYoung
1

Saya baru saja mengalami masalah yang mengganggu dengan fcgiskrip saya . Itu terjadi bahkan sebelum Django dimulai. Kurangnya penebangan sangat menyakitkan. Bagaimanapun, mengarahkan stderr ke file sebagai hal pertama sangat membantu:

#!/home/user/env/bin/python
sys.stderr = open('/home/user/fcgi_errors', 'a')
jozxyqk
sumber