Come gestire il report degli errori¶
Quando esponi un sito pubblico, dovresti sempre disattivare DEBUG
. Questo renderà il tuo server molto più veloce, e inoltre previene di mostrare a utenti malevoli i dettagli della tua applicazione che possono essere rivelati dalle pagine di errore.
Tuttavia, l’esecuzione con DEBUG
impostato a False
comporta che non saranno mai visibili gli errori generati dal tuo sito – al loro posto chiunque vedrà solo le pagine pubbliche di errore. Per tenere traccia degli errori che si verificano in un sito pubblicato, Django può essere configurato per creare reports con dettagli su tali errori.
Rapporti email¶
Errori del server¶
Quando DEBUG
è False, Django invierà una mail agli utenti citati nel setting ADMINS
ogni volta che il tuo codice lancerà un’eccezione non gestita e che risulterà come un error interno del server ( in poche parole, per ogni risposta con un codice HTTP 500 or maggiore ). Questo comporta un’immediata notifica agli amministratori di qualsiasi errore. Le persone specificate nel setting ADMINS
riceveranno un descrizione dell’errore, un traceback Python completo, e i dettagli della richiesta HTTP che ha generato gli errori.
Nota
Per inviare e-mail, Django richiede alcune impostazioni che gli dicono come connettersi al tuo server di posta. Come minimo dovrai specificare EMAIL_HOST
e presumibilmente EMAIL_HOST_USER
e EMAIL_HOST_PASSWORD
, anche se altre impostazioni potrebbero essere richieste a seconda della configurazione del tuo mail server. Consulta </ref/settings> per una lista completa delle impostazioni email
Di default, Django invierà le email da root@localhost. Ma, qualche mail provider rifiuta tutte le mail da questo indirizzo. Per utilizzare un indirizzo diverso, modifica il setting SERVER_EMAIL
Per attivare questo comportamento, inserisci l’indirizzo email del destinatario nella configurazione ADMINS
.
Vedi anche
Le email di errori relativi al server sono inviate usando il framework di logging, puoi personalizzare questo comportamento in personalizza la configurazione del sistema di logging.
Errori 404¶
Django può essere configurato per inviare via email errori relativi ai link non funzionanti (errore 404 «pagina non trovata»). Django invia email relative ad errori 404 quando:
DEBUG
èFalse
;- La tua impostazione
MIDDLEWARE
includedjango.middleware.common.BrokenLinkEmailsMiddleware
.
Se queste condizioni sono soddisfatte, Django invierà un’e-mail agli utenti elencati nell’impostazione MANAGERS
ogni volta che il tuo codice genera un 404 e la richiesta ha un referer. Non si preoccupa di inviare e-mail per i 404 che non hanno un referer: di solito si tratta di persone che digitano URL non funzionanti o bot Web non funzionanti. Ignora anche i 404 quando il referer è uguale all’URL richiesto, poiché questo comportamento è dovuto anche a bot web rotti.
Nota
BrokenLinkEmailsMiddleware
deve essere inserita prima di ogni altro middleware che intereccetti gli errori 404, come LocaleMiddleware
o FlatpageFallbackMiddleware
. Inseriscilo verso l’inizio del tuo setting MIDDLEWARE
.
Puoi dire a Django di smettere di segnalare particolari 404 modificando l’impostazione IGNORABLE_404_URLS
. Dovrebbe essere un elenco di oggetti di espressioni regolari compilati. Per esempio:
import re
IGNORABLE_404_URLS = [
re.compile(r'\.(php|cgi)$'),
re.compile(r'^/phpmyadmin/'),
]
In questo esempio, un 404 a qualsiasi URL che finisce con .php
oppure .cgi
non verrà riportato.Inoltre nessuna URL inizierà con /phpmyadmin/`.
Gli esempi seguenti mostrano come escludere alcune URLs standard che i browser ed i crawler richiedono con frequenza:
import re
IGNORABLE_404_URLS = [
re.compile(r'^/apple-touch-icon.*\.png$'),
re.compile(r'^/favicon\.ico$'),
re.compile(r'^/robots\.txt$'),
]
(Nota bene che queste sono espressioni regolari, quindi mettiamo un backslash prima del punto per assicurarci l’interpretazione come carattere)
Se desideri personalizzare ulteriormente il comportamento di django.middleware.common.BrokenLinkEmailsMiddleware
(ad esempio per ignorare le richieste provenienti dai web crawler), dovresti ereditare la classe e sovrascrivere i suoi metodi.
Vedi anche
Gli errori 404 vengono registrati utilizzando il logging framework. Di default, queste registrazioni sul log vengono ignorate, ma puoi usarle per la segnalazione di errori scrivendo un handler :doc:`configuring logging </topics/logging> “ in modo appropriato.
Filtra i report di errore¶
Avvertimento
Il filtraggio dei dati sensibili è un problema difficile ed è quasi impossibile garantire che i dati sensibili non vengano trasmessi in un report di errore. Pertanto, i report di errore dovrebbero essere disponibili solo per i membri del team affidabili e dovresti evitare di trasmettere report di errore non crittati su Internet (ad esempio tramite e-mail).
Filtraggio informazioni sensibili¶
I report sugli errori sono davvero utili per il loro debug, quindi è generalmente utile registrare quante più informazioni possibili a riguardo. Ad esempio, per impostazione predefinita Django registra il full traceback per l’eccezione sollevata, le variabili locali di ogni traceback frame e i attributes di HttpRequest
.
Comunque, a volte alcuni tipi di informazioni possono essere troppo sensibili e quindi non può essere appropriato tenere traccia ad esempio, della password o del numero di carta di credito di un utente. Quindi oltre a filtrare le impostazioni che sono sensibili come descritto nella documentazione DEBUG
, Django offre una serie di decoratori di funzioni che ti aiutano a controllare quali informazioni debbano essere filtrate sul report degli errori in ambiente di produzione (cioè con DEBUG
impostato a False
): sensitive_variables()
e sensitive_post_parameters()
.
-
sensitive_variables
(*variables)¶ Se una funzione (sia essa una view o una callback regolare) nel tuo codice usa variabili locali suscettibili di contenere infomazioni sensibili, puoi evitare che i valori di quelle variabili vengano inclusi nei report degli errori usando il decoratore
sensitive_variables
:from django.views.decorators.debug import sensitive_variables @sensitive_variables('user', 'pw', 'cc') def process_info(user): pw = user.pass_word cc = user.credit_card_number name = user.name ...
Nell’esempio sopra, i valori delle variabili
user
,pw
ecc
verranno nascosti e sostituiti con asterischi (**********
) nei report di errore, mentre verrà mostrato il valore della variabilename
.Per nascondere sistematicamente tutte e variabili locali di una funzione dal sistema di gestione degli errori nei log, non indicare alcun argomento al decoratore
sensitive_variables
:@sensitive_variables() def my_function(): ...
Quando si utilizzano decoratori multipli
Se la variabile che vuoi nascondere è anche un argomento di funzione (ad es. “”
user
” nell’esempio seguente), e se la funzione decorata ha più decoratori, assicurati di posizionare@sensitive_variables
in cima alla serie di decoratori. In questo modo nasconderà anche l’argomento della funzione mentre viene passato attraverso gli altri decoratori:@sensitive_variables('user', 'pw', 'cc') @some_decorator @another_decorator def process_info(user): ...
-
sensitive_post_parameters
(*parameters)¶ Se una delle tue view riceve un oggetto
HttpRequest
conPOST parameters
suscettibile di contenere informazioni riservate, puoi impedire che i valori di tali parametri siano inclusi nei report di error utilizzando il decoratoresensitive_post_parameters
:from django.views.decorators.debug import sensitive_post_parameters @sensitive_post_parameters('pass_word', 'credit_card_number') def record_user_profile(request): UserProfile.create( user=request.user, password=request.POST['pass_word'], credit_card=request.POST['credit_card_number'], name=request.POST['name'], ) ...
Nell’esempio di cui sopra, i valori dei parametri di POST per
pass_word
ecredit_card_number
saranno nascosti e rimpiazzati con degli asterischi (**********
) nella rappresentazione della request nel report degli errori, dove invece il valore del parametroname
sarà mostrato.Per nascondere sistematicamente tutti i parametri di una richiesta POST nel report degli errori, non inserire alcun parametro al decoratore
sensitive_post_parameters
@sensitive_post_parameters() def my_view(request): ...
Tutti i parametri in POST sono sistematicamente filtrati dai report degli errori per alcune view
django.contrib.auth.views
(login
,password_reset_confirm
,password_change
,add_view
euser_change_password
nell’amministrazioneauth
) per prevenire la fuoriuscita di informazioni sensibili come ad esempio le password utente.
Rapporti di errore personalizzati¶
Tutto ciò che fanno sensitive_variables()
e sensitive_post_parameters()
è, rispettivamente, annotare la funzione decorata con i nomi delle variabili sensibili e annotare l’oggetto HttpRequest
con i nomi dei parametri POST sensibili, in modo che le informazioni possona essere successivamente filtrate dai report quando si verifica un errore. Il vero filtro viene eseguito dal filtro di report degli errori predefinito di Django: django.views.debug.SafeExceptionReporterFilter
. Questo filtro utilizza le annotazioni dei decoratori per sostituire i valori corrispondenti con gli sterischi (**********
) quando vengono prodotti i report di errore. Se desideri sovrascrivere o personalizzare questo comportamento predefinito per l’intero sito, devi definire la tua classe di filtro e dire a Django di usarla tramite l’impostazione DEFAULT_EXCEPTION_REPORTER_FILTER
:
DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
Puoi controllare in modo più granulare quale filtro utilizzare all’interno di una vista configurando il parametro exception_reporter_filter
della HttpRequest
:
def my_view(request):
if request.user.is_authenticated:
request.exception_reporter_filter = CustomExceptionReporterFilter()
...
La tua classe del filtro personalizzato ha bisogno di ereditare da django.views.debug.SafeExceptionReporterFilter
e può sovrascrivere i seguenti attributi e metodi:
-
class
SafeExceptionReporterFilter
¶ -
cleansed_substitute
¶ Il carattere da utilizzare per rimpiazzare valori sensibili. Di default viene rimpiazzato il valore di stringhe sensibili con l’asterisco (
**********
).
Un oggetto di espressione regolare compilato per trovare le impostazioni ed i valori
request.META
considerati sensibili. In modo predefinito è equivalente a:import re re.compile(r'API|TOKEN|KEY|SECRET|PASS|SIGNATURE', flags=re.IGNORECASE)
-
is_active
(request)¶ Restituisce
True
per attivare il filtro inget_post_parameters()
eget_traceback_frame_variables()
. Di default, il filtro è attivo seDEBUG
isFalse
. Nota che i valori sensibilirequest.META
sono sempre filtrati così come i valori di impostazioni sensibili, come descritto nella documentazione diDEBUG
.
-
get_post_parameters
(request)¶ Restituisce un dizionario filtrato di parametri POST. I valori sensibili sono rimpiazzati con
cleansed_substitute
.
-
get_traceback_frame_variables
(request, tb_frame)¶ Restituisce un dizionario filtrato di variabili locali per una data finestra di traceback. I valori sensibili sono rimpiazzati con
cleansed_substitute
.
-
Se necessiti di personalizzare i report degli errori oltre ai filtri, potresti specificare una classe personalizzata per il report degli errori definendo l’impostazione DEFAULT_EXCEPTION_REPORTER
:
DEFAULT_EXCEPTION_REPORTER = 'path.to.your.CustomExceptionReporter'
Il reporter delle eccezioni è resposabile di compilare i dati per il report delle eccezioni e di formattarli come HTML in modo appropriato. (Il reporter delle eccezioni usa DEFAULT_EXCEPTION_REPORTER_FILTER
quando prepara i dati di report delle eccezioni).
La tua classe report personalizzata deve ereditare da django.views.debug.ExceptionReporter
.
-
class
ExceptionReporter
¶ -
html_template_path
¶ Proprietà che restituisce un
pathlib.Path
che rappresenta il percorso assoluto sul filesystem di un template per fare render della rappresentazione HTML dell’eccezione. E” predefinito il template che offre Django.
-
text_template_path
¶ Proprietà che restituisce un
pathlib.Path
che rappresenta il percorso assoluto sul filesystem di un template per fare render della rappresentazione in plain-text dell’eccezione. E” predefinito il template che offre Django.
-
get_traceback_data
()¶ Restituisce un dizionario che contiene le informazioni utili per l’analisi
Questa è il punto principale dell’estensione per personalizzare i report delle eccezioni, per esempio:
from django.views.debug import ExceptionReporter class CustomExceptionReporter(ExceptionReporter): def get_traceback_data(self): data = super().get_traceback_data() # ... remove/add something here ... return data
-
get_traceback_html
()¶ Restituisce la versione HTML del report dell’eccezione
Usato per la versione HTML del debug della pagina di errore 500 HTTP.
-
get_traceback_text
()¶ Restituisce una versione testuale del resoconto dell’eccezione
Usato per la versione testuale del debug della pagina di errore 500 HTTP e report email.
-
Così come con la classe filtro, puoi controllare quale classe per il report di eccezioni usare dentro ad ogni view impostando l’attributo exception_reporter_class
di HttpRequest
:
def my_view(request):
if request.user.is_authenticated:
request.exception_reporter_class = CustomExceptionReporter()
...
Vedi anche
Puoi anche approntare un report degli errori personalizzato scrivendo una parte di middleware delle eccezioni. personalizzato. Se scrivi un report degli errori personalizzato, è una buona idea simulare la gestione degli errori built-in di Django e fare report/log degli errori solo se DEBUG
è False
.