2008-10-26 8 views
160

Also, wenn Sie mit der Entwicklung spielen kann ich einfach settings.DEBUG auf True setzen und wenn ein Fehler auftritt, kann ich es schön formatiert sehen, mit guten Stack-Trace und Informationen anfordern.Wie Log-Server-Fehler auf Django-Sites

Aber auf Art von Produktionsstätte würde ich eher verwenden DEBUG=False und zeigen Besucher einige Standardfehler 500 Seiten mit Informationen, die ich über die Festsetzung dieser Fehler in diesem Moment gerade arbeite;)
Zugleich würde Ich mag eine Möglichkeit zu haben, all diese Informationen (Stack-Trace und Request-Informationen) in eine Datei auf meinem Server zu schreiben - so kann ich sie einfach auf meine Konsole ausgeben und Fehler scrollen sehen, per E-Mail das Protokoll an mich stündlich oder so ähnlich.

Welche Protokollierungslösungen würden Sie für eine Django-Site empfehlen, die diese einfachen Anforderungen erfüllen würde? Ich habe die Anwendung läuft als fcgi Server und ich benutze Apache-Webserver als Frontend (obwohl zu Lighttpd gehen).

+0

etwas vom Schlachtfeld: http://dlo.me/what-to-do-when-your-site-goes-viral/ – Cherian

+1

Sentry zum Anzeigen von Protokollen: http: //readthedocs.org/docs/sentry/en/latest/index.html – Cherian

Antwort

87

Nun, wenn DEBUG = False, wird Django automatisch eine vollständige Traceback von jedem Fehler an jede Person in der ADMINS Einstellung Mailing, die Sie ziemlich kostenlos erhalten Benachrichtigungen. Wenn Sie mehr feinkörnige Steuerung erhalten möchten, können Sie Ihre Einstellungen eine Middleware-Klasse schreiben und fügen Sie die eine Methode namens process_exception() definiert, die Zugriff auf die Ausnahme haben wird, die ausgelöst wurde:

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

Ihre process_exception() Methode kann dann ausführen, welche Art von Protokollierung Sie möchten: Schreiben an die Konsole, Schreiben in eine Datei, etc.

Edit: obwohl es ein bisschen weniger nützlich ist, können Sie auch auf die got_request_exception Signal hören, Diese Nachricht wird gesendet, wenn während der Verarbeitung der Anforderung eine Ausnahme auftritt:

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

Dies gilt nicht geben Sie auf das Ausnahmeobjekt zuzugreifen, jedoch, so dass die Middleware-Methode viel einfacher zu handhaben ist.

+6

Beachten Sie, dass die Verwendung von 'logging.exception ('Some message')' mit Pythons Standard-Logging-Modul gut funktioniert ein sginaler Handler für 'got_request_exception', wenn Sie nur Stack-Traces abmelden wollen. Mit anderen Worten, das Traceback ist immer noch in 'got_request_exception' verfügbar. –

+6

Aber wenn Sie keine E-Mail-Setup haben, wird das nicht funktionieren, oder? – Alper

30

Offensichtlich James ist richtig, aber wenn man in einem Datenspeicher Ausnahme anmelden will, gibt es ein paar Open-Source-Lösungen, die bereits zur Verfügung:

1) Crashlog ist eine gute Wahl: http://code.google.com/p/django-crashlog/

2) Db -Log ist auch eine gute Wahl: http://code.google.com/p/django-db-log/

Was ist der Unterschied zwischen den beiden? Fast nichts, was ich sehen kann, also wird einer ausreichen.

Ich habe beide verwendet und sie funktionieren gut.

39

django-db-log, in einer anderen Antwort erwähnt, wurde ersetzt:

https://github.com/dcramer/django-sentry

+0

Für den Rekord: http://www.davidcramer.net/code/python/36302/keeping-your-logging-compatible-with-sentry.html –

+0

Danke Tomoasz. Siehe auch http://blog.disqus.com/post/1178923988/django-sentry – tobych

72

Django Sentry ist ein guter Weg zu gehen, wie bereits erwähnt, aber es ist ein wenig Arbeit beteiligt bei der richtigen Einrichtung (als separate Website).Wenn Sie einfach alles auf eine einfache Textdatei hier anmelden möchten ist die Protokollierungskonfiguration in Ihrer 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 
     }, 
    }, 
} 
+0

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

+1

Ein kleiner Tippfehler für den Fall, dass jemand ausschneidet: "propagiere" statt "propagiere" am Ende. – user1228295

+0

Danke! Tippfehler behoben. – EMP

11

einiger Zeit setzen seit EMP am nützlichsten Code Vorlage übergeben. Ich habe es gerade implementiert, und während ich mit der manage.py Option herumstolziere, um einen Fehler zu finden, habe ich eine Verwarnungs-Warnung erhalten, dass mit meiner aktuellen Version von Django (1.5.?) Jetzt ein require_debug_false Filter ist benötigt für den mail_admins-Handler. 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 
     }, 
    }, 
} 
+0

Ich bin gespannt, ob die mail_admins Handler (und django.request Logger) notwendig ist, da Sie "disable_existing_loggers" haben: False und replizieren einfach Standard-Django-Protokollierung mit diesem Handler (und Logger). Ich werde aktualisieren, wenn ich getestet habe. – DylanYoung

1

ich nur ein lästiges Problem mit meinem fcgi Skript hatte. Es geschah, bevor Django überhaupt begann. Der Mangel an Protokollierung ist sooo schmerzhaft. Wie auch immer, in eine Datei als erstes, was Umleiten Stderr sehr geholfen:

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