คุณจะบันทึกข้อผิดพลาดของเซิร์ฟเวอร์บนเว็บไซต์ django ได้อย่างไร


175

ดังนั้นเมื่อเล่นกับการพัฒนาที่ผมก็สามารถกำหนดsettings.DEBUGไปTrueและหากมีข้อผิดพลาด occures ฉันสามารถดูได้จัดรูปแบบเป็นอย่างดีมีร่องรอยดีสแต็คและขอข้อมูล

แต่ในเว็บไซต์ผลิตฉันควรใช้DEBUG=Falseและแสดงให้ผู้เยี่ยมชมมีข้อผิดพลาดมาตรฐาน 500 หน้าพร้อมข้อมูลที่ฉันกำลังแก้ไขข้อผิดพลาดนี้ในขณะนี้;)
ในขณะเดียวกันฉันต้องการมีวิธีการบันทึกทั้งหมด ข้อมูลเหล่านั้น (การติดตามสแต็คและขอข้อมูล) ไปยังไฟล์บนเซิร์ฟเวอร์ของฉัน - ดังนั้นฉันสามารถส่งออกไปยังคอนโซลของฉันและดูการเลื่อนข้อผิดพลาดส่งอีเมลบันทึกถึงฉันทุกชั่วโมงหรืออะไรทำนองนี้

โซลูชั่นการบันทึกใดที่คุณจะแนะนำสำหรับไซต์ django ซึ่งจะตอบสนองความต้องการง่ายๆเหล่านั้น ฉันมีแอปพลิเคชันทำงานเป็นfcgiเซิร์ฟเวอร์และฉันใช้ apache เว็บเซิร์ฟเวอร์เป็นส่วนหน้า (แม้ว่าจะคิดว่าจะไป lighttpd)


บางอย่างจากสนามรบ: dlo.me/what-to-do-when-your-site-goes-viral
Cherian

2
ยามที่ดูบันทึก: readthedocs.org/docs/sentry/en/latest/index.html
Cherian

ลิงค์ที่แชร์แชร์แชร์ตายไปแล้ว หากคุณลองค้นหา Sentry คุณอาจพบว่ามีเนื้อหาสำหรับอินสแตนซ์ที่เป็นทางการที่จ่ายเงินแล้ว แต่นี่คือลิงก์สำหรับตั้งค่าอินสแตนซ์ที่โฮสต์ด้วยตนเอง: docs.sentry.io/server นอกจากนี้ที่นี่เป็น repo ที่ดูแลรักษาในปัจจุบัน: github .com / getsentry / sentry
lehiester

คำตอบ:


103

เมื่อไรที่DEBUG = FalseDjango จะส่งการติดตามย้อนกลับแบบเต็มของข้อผิดพลาดใด ๆ ไปยังบุคคลที่ระบุในการADMINSตั้งค่าโดยอัตโนมัติซึ่งจะทำให้คุณได้รับการแจ้งเตือนฟรีมาก หากคุณต้องการการควบคุมที่ละเอียดยิ่งขึ้นคุณสามารถเขียนและเพิ่มคลาสมิดเดิลแวร์ที่กำหนดวิธีการที่มีชื่อprocess_exception()ซึ่งจะสามารถเข้าถึงข้อยกเว้นที่เพิ่มขึ้นในการตั้งค่าของคุณ

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

process_exception()วิธีการของคุณสามารถทำการบันทึกประเภทใดก็ได้ที่คุณต้องการ: การเขียนไปยังคอนโซลการเขียนไปยังไฟล์ ฯลฯ ฯลฯ

แก้ไข: แม้ว่าจะมีประโยชน์น้อยกว่าเล็กน้อยคุณสามารถฟังgot_request_exceptionสัญญาณซึ่งจะถูกส่งเมื่อใดก็ตามที่พบข้อยกเว้นระหว่างการประมวลผลคำขอ:

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

สิ่งนี้ไม่ได้ให้สิทธิ์คุณในการเข้าถึงออบเจ็กต์ข้อยกเว้นดังนั้นวิธีการมิดเดิลแวร์จะทำงานได้ง่ายกว่ามาก


7
โปรดทราบว่าการใช้งานlogging.exception('Some message')ร่วมกับโมดูลการบันทึกมาตรฐานของ python นั้นใช้งานได้ดีใน sginal handler สำหรับgot_request_exceptionหากสิ่งที่คุณต้องการทำคือออกจากระบบการติดตามสแต็ก ในคำอื่น ๆ traceback got_request_exceptionจะยังคงมีอยู่ใน
TM

ข้อยกเว้นที่ส่งผ่านไปยัง process_exception ไม่ปรากฏว่ามีการติดตามสแต็กมีวิธีรับหรือไม่
Nick BL

79

Django Sentry เป็นวิธีที่ดีที่จะไปดังที่กล่าวไว้แล้ว แต่มีงานเล็กน้อยที่เกี่ยวข้องในการตั้งค่าอย่างถูกต้อง (เป็นเว็บไซต์แยกต่างหาก) หากคุณเพียงต้องการบันทึกทุกอย่างลงในไฟล์ข้อความแบบง่ายนี่คือการกำหนดค่าการบันทึกที่จะใส่ไว้ในของคุณsettings.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
        },
    },
}

ฉันเห็นด้วยฉันรักยาม! ฉันต้องการพอร์ต. Net (ใช้งานโครงการ. Net เมื่อเร็ว ๆ นี้)
Gromer

1
ตัวพิมพ์เล็ก ๆ ในกรณีที่มีใครบางคนกำลังตัด & วาง: "propogate" แทนที่จะเป็น "เผยแพร่" ในตอนท้าย
user1228295

3
'include_html': Trueไม่เพียงแค่ทำให้อีเมล "ดีกว่า"! มันรวมถึงการย้อนกลับเต็มรูปแบบรวมถึงค่าของการตั้งค่าและตัวแปรท้องถิ่น ตามเอกสารนี้เป็นความกังวลด้านความปลอดภัย: docs.djangoproject.com/en/1.8/topics/logging/...
โทมัส

1
ฉันอยากรู้ว่าตัวจัดการ mail_admins (และ django.request logger) เป็นสิ่งจำเป็นหรือไม่เนื่องจากคุณมี 'disable_existing_loggers': เท็จและเป็นเพียงการทำซ้ำการบันทึก django เริ่มต้นด้วยตัวจัดการนี้ (และคนตัดไม้) ฉันจะอัปเดตเมื่อฉันทดสอบ
DylanYoung

โปรดอัปเดตคำตอบนี้ จาก django1.9 บันทึกการเปลี่ยนแปลง: การกำหนดค่าการบันทึกเริ่มต้นของ Django ไม่ได้กำหนดตัวบันทึก 'django.request' และ 'django.security' อีกต่อไป
narendra-choudhary


30

เห็นได้ชัดว่า James นั้นถูกต้อง แต่ถ้าคุณต้องการบันทึกข้อยกเว้นในที่เก็บข้อมูลมีโซลูชันโอเพนซอร์สอยู่สองสามที่มีอยู่แล้ว:

1) CrashLog เป็นตัวเลือกที่ดี: http://code.google.com/p/django-crashlog/

2) Db-Log เป็นตัวเลือกที่ดีเช่นกัน: http://code.google.com/p/django-db-log/

ความแตกต่างระหว่างสองคืออะไร? แทบไม่มีอะไรที่ฉันเห็นดังนั้นทั้งคู่จะพอเพียง

ฉันใช้ทั้งสองอย่างและทำงานได้ดี


15

เวลาผ่านไปนับตั้งแต่การส่งรหัสที่เป็นประโยชน์ที่สุดของ EMP ตอนนี้ฉันเพิ่งติดตั้งมันและในขณะที่เดินไปรอบ ๆ พร้อมกับบางส่วนของตัวเลือก Manage.py เพื่อพยายามไล่ล่าบั๊กฉันได้รับคำเตือนการคัดค้านถึงผลกระทบที่กับ Django เวอร์ชันปัจจุบันของฉัน (1.5.?) ตัวกรอง require_debug_false จำเป็นสำหรับตัวจัดการ mail_admins

นี่คือรหัสที่แก้ไข:

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
        },
    },
}

ฉันอยากรู้ว่าตัวจัดการ mail_admins (และ django.request logger) เป็นสิ่งจำเป็นหรือไม่เนื่องจากคุณมี 'disable_existing_loggers': เท็จและเป็นเพียงการทำซ้ำการบันทึก django เริ่มต้นด้วยตัวจัดการนี้ (และคนตัดไม้) ฉันจะอัปเดตเมื่อฉันทดสอบ
DylanYoung

1

ฉันเพิ่งมีปัญหาที่น่ารำคาญกับfcgiสคริปต์ของฉัน มันเกิดขึ้นก่อนที่จะเริ่ม django การขาดการเข้าสู่ระบบนั้นเจ็บปวดมาก อย่างไรก็ตามการเปลี่ยนเส้นทาง stderr ไปยังไฟล์เป็นสิ่งแรกที่ช่วยได้มาก:

#!/home/user/env/bin/python
sys.stderr = open('/home/user/fcgi_errors', 'a')
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.