Come si registrano gli errori del server sui siti Django


175

Così, quando si gioca con lo sviluppo posso solo impostare settings.DEBUGper Truee se un errore occures posso vederlo ben formattato, con la traccia buona stack e informazioni di richiesta.

Ma su un tipo di sito di produzione preferirei usare DEBUG=Falsee mostrare ai visitatori qualche pagina di errore standard 500 con informazioni che sto lavorando per correggere questo bug in questo momento;)
Allo stesso tempo, vorrei avere un modo per registrare tutto quelle informazioni (impila traccia e richiedi informazioni) a un file sul mio server - quindi posso semplicemente inviarlo alla mia console e guardare gli errori scorrere, inviarmi via email il registro ogni ora o qualcosa del genere.

Quali soluzioni di registrazione consiglieresti per un sito django, che soddisferebbe quei semplici requisiti? Ho l'applicazione in esecuzione come fcgiserver e sto usando apache web server come frontend (anche se sto pensando di andare su lighttpd).


qualcosa dal campo di battaglia: dlo.me/what-to-do-when-your-site-goes-viral
Cherian

2
Sentinella per visualizzare i registri: readthedocs.org/docs/sentry/en/latest/index.html
Cherian

Il link che Cherian ha condiviso è ora morto. Se provi a cercare Sentry, è probabile che trovi materiale per la loro istanza ufficiale a pagamento, ma ecco il link per impostare un'istanza self-hosted: docs.sentry.io/server Inoltre, ecco il repository attualmente gestito: github .com / getsentry / sentry
lehiester

Risposte:


103

Bene, quando DEBUG = False, Django invierà automaticamente una traccia completa di qualsiasi errore a ogni persona elencata ADMINSnell'impostazione, il che ti darà le notifiche praticamente gratis. Se desideri un controllo più accurato, puoi scrivere e aggiungere alle tue impostazioni una classe middleware che definisce un metodo denominato process_exception(), che avrà accesso all'eccezione sollevata:

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

Il tuo process_exception()metodo può quindi eseguire qualsiasi tipo di registrazione desideri: scrivere sulla console, scrivere su un file, ecc. Ecc.

Modifica: sebbene sia un po 'meno utile, puoi anche ascoltare il got_request_exceptionsegnale, che verrà inviato ogni volta che si verifica un'eccezione durante l'elaborazione della richiesta:

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

Questo non ti dà accesso all'oggetto eccezione, tuttavia, quindi il metodo middleware è molto più facile da lavorare.


7
Si noti che l'utilizzo logging.exception('Some message')con il modulo di registrazione standard di Python funziona bene in un gestore marginale per got_request_exception, se tutto ciò che si sta cercando di fare è disconnettere le tracce dello stack. In altre parole, il traceback è ancora disponibile in got_request_exception.
TM.

l'eccezione passata a process_exception non sembra avere la traccia dello stack, c'è un modo per ottenerlo?
Nick BL,

79

Django Sentry è una buona strada da percorrere, come già accennato, ma è necessario un po 'di lavoro per configurarlo correttamente (come sito Web separato). Se vuoi semplicemente registrare tutto in un semplice file di testo, ecco la configurazione di registrazione da inserire nel tuosettings.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
        },
    },
}

Sono d'accordo, adoro Sentry! Voglio avere una porta .Net di esso (di recente ho lavorato su progetti .Net).
Gromer,

1
Un piccolo errore nel caso in cui qualcuno stia tagliando e incollando: "propaga" invece di "propagare" alla fine.
user1228295

3
'include_html': TrueNON semplicemente rende le e-mail "più belle"! Include un traceback completo, inclusi i valori di impostazioni e variabili locali. In base ai documenti, si tratta di un problema di sicurezza: docs.djangoproject.com/en/1.8/topics/logging/…
Thomas,

1
Sono curioso di sapere se il gestore mail_admins (e il logger django.request) è necessario dato che hai 'disable_existing_loggers': False e stai semplicemente replicando la registrazione predefinita di django con questo gestore (e logger). Aggiornerò quando ho testato.
DylanYoung,

Si prega di aggiornare questa risposta. Da django1.9 change-log: la configurazione di registrazione predefinita di Django non definisce più i logger 'django.request' e 'django.security'.
Narendra-Choudhary,



15

È passato del tempo dall'invio del codice più utile di EMP. L'ho implementato proprio ora e, mentre mi lanciavo con qualche opzione manage.py, per cercare di inseguire un bug, ho ricevuto un avviso di deprecazione secondo cui con la mia attuale versione di Django (1.5.?) È ora disponibile un filtro request_debug_false necessario per il gestore mail_admins.

Ecco il codice rivisto:

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

Sono curioso di sapere se il gestore mail_admins (e il logger django.request) è necessario dato che hai 'disable_existing_loggers': False e stai semplicemente replicando la registrazione predefinita di django con questo gestore (e logger). Aggiornerò quando ho testato.
DylanYoung,

1

Ho appena avuto un fastidioso problema con la mia fcgisceneggiatura. È successo prima ancora che django iniziasse. La mancanza di registrazione è così dolorosa. Ad ogni modo, il reindirizzamento di stderr a un file come prima cosa ha aiutato molto:

#!/home/user/env/bin/python
sys.stderr = open('/home/user/fcgi_errors', 'a')
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.