Wie protokollieren Sie Serverfehler auf Django-Sites?


175

Wenn ich also mit der Entwicklung spiele, kann ich einfach festlegen settings.DEBUG, Trueund wenn ein Fehler auftritt, kann ich sehen, dass sie gut formatiert ist, mit guter Stapelverfolgung und Anforderungsinformationen.

Aber auf einer Art Produktionsstätte würde ich lieber DEBUG=Falseeine Standardfehler-500-Seite mit Informationen verwenden und anzeigen, an denen ich gerade arbeite, um diesen Fehler zu beheben;)
Gleichzeitig möchte ich eine Möglichkeit haben, alle zu protokollieren Diese Informationen (Stapelverfolgung und Anforderungsinformationen) werden in eine Datei auf meinem Server übertragen. Ich kann sie also einfach auf meiner Konsole ausgeben und Fehler beim Scrollen beobachten, das Protokoll jede Stunde per E-Mail an mich senden oder so etwas.

Welche Protokollierungslösungen würden Sie für eine Django-Site empfehlen, die diese einfachen Anforderungen erfüllt? Ich habe die Anwendung als fcgiServer ausgeführt und verwende Apache-Webserver als Frontend (obwohl ich daran denke, auf lighttpd zu gehen).




Der Link, den Cherian geteilt hat, ist jetzt tot. Wenn Sie versuchen, nach Sentry zu suchen, werden Sie wahrscheinlich Material für die kostenpflichtige offizielle Instanz finden. Hier ist jedoch der Link zum Einrichten einer selbst gehosteten Instanz: docs.sentry.io/server Hier ist auch das aktuell gepflegte Repo: github .com / getsentry / sentry
lehiester

Antworten:


103

Nun, wenn DEBUG = False, Django wird automatisch eine vollständige Rückverfolgung aller Fehler an jede in der ADMINSEinstellung aufgeführte Person senden, wodurch Sie so gut wie kostenlos benachrichtigt werden. Wenn Sie eine genauere Steuerung wünschen, können Sie eine Middleware-Klasse schreiben und zu Ihren Einstellungen hinzufügen, die eine Methode mit dem Namen definiert process_exception(), die Zugriff auf die Ausnahme hat, die ausgelöst wurde:

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

Ihre process_exception()Methode kann dann jede Art von Protokollierung durchführen, die Sie möchten: Schreiben in die Konsole, Schreiben in eine Datei usw. usw.

Bearbeiten: Obwohl es etwas weniger nützlich ist, können Sie auch auf das got_request_exceptionSignal warten, das gesendet wird, wenn während der Anforderungsverarbeitung eine Ausnahme auftritt:

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

Dadurch erhalten Sie jedoch keinen Zugriff auf das Ausnahmeobjekt, sodass die Middleware-Methode viel einfacher zu handhaben ist.


7
Beachten Sie, dass die Verwendung logging.exception('Some message')mit dem Standardprotokollierungsmodul von Python in einem Sginal-Handler einwandfrei funktioniert got_request_exception, wenn Sie nur Stack-Traces abmelden möchten . Mit anderen Worten, der Traceback ist weiterhin in verfügbar got_request_exception.
TM.

Die an process_exception übergebene Ausnahme scheint keinen Stack-Trace zu haben. Gibt es eine Möglichkeit, dies zu erreichen?
Nick BL

79

Django Sentry ist, wie bereits erwähnt, ein guter Weg, aber es ist ein wenig Arbeit erforderlich, ihn ordnungsgemäß einzurichten (als separate Website). Wenn Sie nur alles in einer einfachen Textdatei protokollieren möchten, finden Sie hier die Protokollierungskonfiguration, die Sie in Ihre Datei einfügen könnensettings.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
        },
    },
}

Ich stimme zu, ich liebe Sentry! Ich möchte einen .Net-Port davon haben (habe in letzter Zeit an .Net-Projekten gearbeitet).
Gromer

1
Ein kleiner Tippfehler für den Fall, dass jemand ausschneidet und einfügt: "propagieren" statt "verbreiten" am Ende.
user1228295

3
'include_html': Truemacht die E-Mails NICHT einfach "schöner"! Es enthält einen vollständigen Traceback, einschließlich der Werte von Einstellungen und lokalen Variablen. Laut
Thomas

1
Ich bin gespannt, ob der mail_admins-Handler (und der django.request-Logger) erforderlich sind, da Sie 'disable_existing_loggers': False haben und einfach die Standard-django-Protokollierung mit diesem Handler (und Logger) replizieren. Ich werde aktualisieren, wenn ich getestet habe.
DylanYoung

Bitte aktualisieren Sie diese Antwort. Aus django1.9 change-log: Die Standardprotokollierungskonfiguration von Django definiert nicht mehr die Protokollierer 'django.request' und 'django.security'.
Narendra-Choudhary



15

Seit der hilfreichsten Codeübermittlung von EMP ist einige Zeit vergangen. Ich habe es gerade implementiert, und während ich mit einer Option "manage.py" herumwirbelte, um zu versuchen, einen Fehler zu beseitigen, erhielt ich eine Verwerfungswarnung dahingehend, dass mit meiner aktuellen Version von Django (1.5.?) Jetzt ein require_debug_false-Filter vorhanden ist wird für den mail_admins-Handler benötigt.

Hier ist der überarbeitete Code:

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

Ich bin gespannt, ob der mail_admins-Handler (und der django.request-Logger) erforderlich sind, da Sie 'disable_existing_loggers': False haben und einfach die Standard-django-Protokollierung mit diesem Handler (und Logger) replizieren. Ich werde aktualisieren, wenn ich getestet habe.
DylanYoung

1

Ich hatte gerade ein nerviges Problem mit meinem fcgiSkript. Es geschah, bevor Django überhaupt anfing. Der Mangel an Protokollierung ist sooo schmerzhaft. Auf jeden Fall hat es sehr geholfen, stderr als erstes in eine Datei umzuleiten:

#!/home/user/env/bin/python
sys.stderr = open('/home/user/fcgi_errors', 'a')
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.