web-dev-qa-db-fra.com

Comment enregistrez-vous les erreurs de serveur sur Django sites

Donc, quand je joue avec le développement, je peux juste mettre settings.DEBUG to True et si une erreur survient, je peux la voir bien formatée, avec un bon suivi de la pile et des informations de demande.

Mais sur un type de site de production, je préfère utiliser DEBUG=False et montre aux visiteurs des pages d'erreur standard 500 contenant des informations sur lesquelles je travaille actuellement à la résolution de ce bug;)
En même temps, j'aimerais pouvoir enregistrer toutes ces informations (trace de pile et informations de demande) dans un fichier sur mon serveur - afin que je puisse simplement les exporter sur ma console et voir les erreurs défiler, envoyez-moi le journal toutes les heures ou quelque chose comme ça.

Quelles solutions de journalisation recommanderiez-vous pour un site Django répondant à ces exigences simples? J'ai l'application en cours d'exécution en tant que serveur fcgi et j'utilise le serveur Web Apache comme interface frontale (bien que je pense à passer à lighttpd).

169
kender

Eh bien, lorsque DEBUG = False, Django enverra automatiquement un suivi complet de toute erreur à chaque personne répertoriée dans le paramètre ADMINS, ce qui vous permet d'obtenir des notifications assez longtemps pour. Si vous souhaitez un contrôle plus fin, vous pouvez écrire et ajouter à vos paramètres une classe de middleware qui définit une méthode nommée process_exception(), qui aura accès à l'exception qui a été déclenchée:

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

Votre méthode process_exception() peut alors exécuter le type de journalisation souhaité: écriture sur console, écriture dans un fichier, etc., etc.

Edit: bien que ce soit un peu moins utile, vous pouvez également écouter le signal got_request_exception, Qui sera envoyé chaque fois qu’une exception se produira lors du traitement de la demande:

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

Cela ne vous donne pas , cependant, de sorte que la méthode middleware est beaucoup plus facile à utiliser.

98
James Bennett

Comme déjà mentionné, Django Sentry est une bonne solution, mais sa mise en place nécessite un peu de travail (en tant que site Web séparé). Si vous souhaitez simplement tout enregistrer dans un fichier texte simple, voici la configuration de journalisation à mettre dans votre 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
        },
    },
}
77
EMP

Django-db-log, mentionné dans une autre réponse, a été remplacé par:

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

39
tobych

Bien entendu, James a raison, mais si vous souhaitez enregistrer des exceptions dans un magasin de données, quelques solutions open source sont déjà disponibles:

1) CrashLog est un bon choix: http://code.google.com/p/Django-crashlog/

2) Db-Log est également un bon choix: http://code.google.com/p/Django-db-log/

Quelle est la différence entre les deux? Presque rien que je puisse voir, donc l'un ou l'autre suffira.

J'ai utilisé les deux et ils fonctionnent bien.

30
montylounge

Un peu de temps s'est écoulé depuis la soumission de code la plus utile d'EMP. Je viens tout juste de le mettre en œuvre, et tout en essayant de trouver une option de gestion pour essayer de chasser un bogue, j'ai reçu un avertissement de dépréciation indiquant qu'avec ma version actuelle de Django ( 1.5.?) Un filtre require_debug_false est maintenant nécessaire pour le gestionnaire mail_admins.

Voici le code révisé:

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
        },
    },
}
13
Mike O'Connor

Je viens d'avoir un problème avec mon script fcgi. Cela se produisait avant Django a même commencé. Le manque de journalisation est tellement douloureux. Quoi qu'il en soit, rediriger stderr vers un fichier dès le début a beaucoup aidé:

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