2011-05-04 9 views
17

Ho eseguito alcune ricerche, ma mi chiedo se qualcuno abbia uno snippet di una configurazione di registrazione per fare in modo che Django emetta solo una traccia dello stack su stdout (così posso vederlo nella finestra Terminale) quando incontra un errore durante una richiesta. Questo è specifico per lo sviluppo/debugging locale e principalmente per quando faccio richieste post AJAX e devo guardare l'HTML in Firebug per capire su quale riga si è verificato l'errore.Stampa una traccia dello stack su stdout sugli errori in Django durante l'utilizzo di manage.py runserver

+0

"Finestra terminale"? Stai eseguendo 'django-admin.py runserver'? –

+0

Sì, 'manage.py runserver' in locale, ma questo sarebbe utile anche per la produzione, anche se ricevo e-mail, quindi meno di un problema. – Bialecki

+0

l'approccio "produzione" dipende da come si è integrati con Apache, quindi sarà necessario fornire ulteriori dettagli su tale configurazione per essere sicuri di averlo compreso. –

risposta

20

È possibile creare un pezzo di middleware per farlo. Ecco un frammento modificato sto usando per un progetto:

class ExceptionLoggingMiddleware(object): 
    def process_exception(self, request, exception): 
     import traceback 
     print traceback.format_exc() 

Luogo questo gestore nella parte middleware delle impostazioni di Django.

0

Gestore WSCI di sottoclasse, esegui tutto ciò che vuoi con traceback nel tuo handle_uncaught_exception definito e usa il tuo WSGIHandler al posto di quello fornito da django durante la distribuzione.

import traceback 
from django.core.handlers.wsgi import WSGIHandler 

class MyWSGIHandler(WSGIHandler): 
    """WSGI Handler which prints traceback to stderr""" 
    def handle_uncaught_exception(self, request, resolver, exc_info): 
     traceback.print_tb(exc_info[2], file=sys.stderr) 
     return super(WSGIHandler, self).handle_uncaught_exception(request, resolver, exc_info) 

Usato con Apache/mod_wsgi, questo dovrebbe scrivere traceback nel log degli errori di Apache

24

Un altro metodo è con LOGGING. In particolare si ottiene uno stacktrace durante l'esecuzione ./manage.py runserver aggiungendo quanto segue al settings.py di file:

LOGGING = { 
    'version': 1, 
    'handlers': { 
     'console':{ 
      'level':'DEBUG', 
      'class':'logging.StreamHandler', 
     }, 
    }, 
    'loggers': { 
     'django.request': { 
      'handlers':['console'], 
      'propagate': True, 
      'level':'DEBUG', 
     } 
    }, 
} 

Questa sintassi viene dalla documentazione di Django Configuring Logging e può essere ulteriormente modificato per aumentare o diminuire la quantità di Console- registrazione.

Anche i 5XX risposte sono allevati come messaggi di errore e 4XX risposte sono cresciuti come messaggi di avviso.

Si noti che questa domanda & risposta ha un duplicato 2013 here.

+3

Questo dovrebbe essere il metodo preferito secondo me. Hai molto più controllo su quali logger vuoi usare, cosa vuoi registrare ecc. – Andre

0

Ho avuto un problema simile, ma l'opzione middleware non mi è stata d'aiuto. Il motivo è che sto usando django-jsonview 0.4.3 che fornisce un decoratore che converte un dizionario in una risposta http JSON valida, anche quando la funzione decorata fallisce, quindi il metodo middleware process_exception non viene mai chiamato. Ho controllato il codice di questo decoratore e sembra che si cerca di registrare l'errore di fare questo:

... 
except Exception as e: 
    logger = logging.getLogger('django.request') 
    logger.exception(unicode(e)) 

Tuttavia, non so perché, questo non funziona e non viene registrato nella mia console bash. Dovrei scoprire perché questo accada. Nel frattempo, sto usando un decoratore in più:

def log_errors(func): 
    if not settings.DEBUG: 
     return func 

    def wrapper(request, *args, **kwargs): 
     try: 
      return func(request, *args, **kwargs) 
     except: 
      print traceback.format_exc() 
    return wrapper 

Poi, in tutti i miei punti di vista JSON:

@json_view 
@log_errors 
def my_view(request): 
    .... 
1

io di solito uso questo:

except Exception,e: 
     # Get line 
     trace=traceback.extract_tb(sys.exc_info()[2]) 
     # Add the event to the log 
     output ="Error in the server: %s.\n" % (e) 
     output+="\tTraceback is:\n" 
     for (file,linenumber,affected,line) in trace: 
      output+="\t> Error at function %s\n" % (affected) 
      output+="\t At: %s:%s\n" % (file,linenumber) 
      output+="\t Source: %s\n" % (line) 
     output+="\t> Exception: %s\n" % (e) 

Poi uso "uscita "per qualsiasi cosa ho bisogno: stampare su stdout, inviare una e-mail, ecc ...

11

È st range nessuno ha menzionato l'impostazione DEBUG_PROPAGATE_EXCEPTIONS.Non è per la produzione, ma è molto facile da usare in ambiente di test/debug. Basta aggiungere a settings.py:

DEBUG_PROPAGATE_EXCEPTIONS = True 
+1

Esattamente questa sembra la risposta più appropriata :) – sudhanshu

+0

+1 per quello che vale, dopo un paio d'ore di debug di un problema di DRF e senza più test/opzioni da provare, hai letteralmente salvato la mia giornata ... – jliendo

+0

Questa dovrebbe essere la risposta accettata, grazie mille! –

Problemi correlati