Hur man hanterar felrapportering¶
När du driver en offentlig webbplats bör du alltid stänga av inställningen DEBUG
. Det kommer att göra att din server körs mycket snabbare och kommer också att förhindra att illasinnade användare ser detaljer i din applikation som kan avslöjas av felsidorna.
Men om du kör med DEBUG
inställd på False
innebär det att du aldrig kommer att se fel som genereras av din webbplats - alla kommer istället att se dina offentliga felsidor. Du måste hålla reda på fel som uppstår på distribuerade webbplatser, så Django kan konfigureras för att skapa rapporter med detaljer om dessa fel.
E-postrapporter¶
Serverfel¶
När DEBUG
är False
kommer Django att skicka e-post till de användare som anges i ADMINS
-inställningen när din kod ger upphov till ett ohanterat undantag och resulterar i ett internt serverfel (strängt taget för alla svar med en HTTP-statuskod på 500 eller högre). Detta ger administratörerna omedelbar information om eventuella fel. Inställningen ADMINS
kommer att få en beskrivning av felet, en fullständig Python-spårning och detaljer om HTTP-begäran som orsakade felet.
Observera
För att kunna skicka e-post kräver Django några inställningar som talar om hur den ska ansluta till din e-postserver. Åtminstone måste du ange EMAIL_HOST
och eventuellt EMAIL_HOST_USER
och EMAIL_HOST_PASSWORD
, men andra inställningar kan också krävas beroende på din e-postservers konfiguration. Se :doc:``Dokumentationen för Django-inställningar </ref/settings>` för en fullständig lista över e-postrelaterade inställningar.
Som standard kommer Django att skicka e-post från root@localhost. Vissa e-postleverantörer avvisar dock alla e-postmeddelanden från denna adress. Om du vill använda en annan avsändaradress ändrar du inställningen SERVER_EMAIL
.
För att aktivera det här beteendet måste du ange mottagarnas e-postadresser i inställningen ADMINS
.
Se även
E-postmeddelanden om serverfel skickas med hjälp av loggningsramverket, så du kan anpassa det här beteendet genom att anpassa din loggningskonfiguration.
404 fel¶
Django kan också konfigureras att skicka e-postmeddelanden om fel på brutna länkar (404 ”sidan hittades inte”-fel). Django skickar e-postmeddelanden om 404-fel när:
DEBUG
ärFalse
;Din :inställning:`MIDDLEWARE` inkluderar :klass:`django.middleware.common.BrokenLinkEmailsMiddleware`.
Om dessa villkor är uppfyllda kommer Django att skicka e-post till de användare som anges i inställningen MANAGERS
när din kod ger upphov till en 404 och begäran har en referent. Det bryr sig inte om att skicka e-post för 404 som inte har någon referent - det är vanligtvis människor som skriver in trasiga webbadresser eller trasiga webbrobotar. Det ignorerar också 404:or när referensen är lika med den begärda webbadressen, eftersom detta beteende också kommer från trasiga webbrobotar.
Observera
BrokenLinkEmailsMiddleware
måste visas före annan middleware som fångar upp 404-fel, till exempel LocaleMiddleware
eller FlatpageFallbackMiddleware
. Placera den högst upp i din MIDDLEWARE
-inställning.
Du kan tala om för Django att sluta rapportera vissa 404:or genom att justera inställningen IGNORABLE_404_URLS
. Det bör vara en lista med kompilerade objekt för reguljära uttryck. Till exempel:
import re
IGNORABLE_404_URLS = [
re.compile(r"\.(php|cgi)$"),
re.compile(r"^/phpmyadmin/"),
]
I det här exemplet kommer en 404 till en URL som slutar med .php
eller .cgi
inte att rapporteras. Det gör inte heller någon URL som börjar med /phpmyadmin/
.
Följande exempel visar hur du utesluter några konventionella webbadresser som webbläsare och sökrobotar ofta begär:
import re
IGNORABLE_404_URLS = [
re.compile(r"^/apple-touch-icon.*\.png$"),
re.compile(r"^/favicon\.ico$"),
re.compile(r"^/robots\.txt$"),
]
(Observera att detta är reguljära uttryck, så vi sätter en backslash framför punkterna för att undkomma dem)
Om du vill anpassa beteendet hos django.middleware.common.BrokenLinkEmailsMiddleware
ytterligare (t.ex. för att ignorera förfrågningar som kommer från webbcrawlers), bör du underordna den och åsidosätta dess metoder.
Se även
404-fel loggas med hjälp av ramverket för loggning. Som standard ignoreras dessa loggposter, men du kan använda dem för felrapportering genom att skriva en hanterare och konfigurera loggning på lämpligt sätt.
Filtrering av felrapporter¶
Varning
Att filtrera känsliga data är ett svårt problem, och det är nästan omöjligt att garantera att känsliga data inte läcker ut i en felrapport. Därför bör felrapporter endast vara tillgängliga för betrodda teammedlemmar och du bör undvika att överföra felrapporter okrypterade över internet (t.ex. via e-post).
Filtrering av känslig information¶
Felrapporter är till stor hjälp vid felsökning, så det är i allmänhet bra att registrera så mycket relevant information om dessa fel som möjligt. Som standard registrerar Django till exempel den fullständiga spårningen för det undantag som uppstod, varje spårningsram lokala variabler och HttpRequest
attributes.
Ibland kan dock vissa typer av information vara för känslig och därmed kanske inte lämplig att hålla reda på, till exempel en användares lösenord eller kreditkortsnummer. Så förutom att filtrera bort inställningar som verkar vara känsliga enligt beskrivningen i DEBUG
-dokumentationen, erbjuder Django en uppsättning funktionsdekoratorer som hjälper dig att kontrollera vilken information som ska filtreras bort från felrapporter i en produktionsmiljö (det vill säga där DEBUG
är inställd på False
): sensitive_variables()
och sensitive_post_parameters()
.
- sensitive_variables(*variables)[source]¶
Om en funktion (antingen en vy eller en vanlig callback) i din kod använder lokala variabler som kan innehålla känslig information, kan du förhindra att värdena på dessa variabler inkluderas i felrapporter med hjälp av dekoratorn
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 ...
I exemplet ovan kommer värdena för variablerna
user
,pw
ochcc
att döljas och ersättas med stjärnor (**********
) i felrapporterna, medan värdet för variabelnname
kommer att avslöjas.För att systematiskt dölja alla lokala variabler i en funktion från felloggar ska du inte ange något argument till dekoratorn
sensitive_variables
:@sensitive_variables() def my_function(): ...
När du använder flera dekoratorer
Om variabeln du vill dölja också är ett funktionsargument (t.ex. ’
user
’ i följande exempel), och om den dekorerade funktionen har flera dekoratorer, se då till att placera@sensitive_variables
högst upp i dekoratorkedjan. På så sätt kommer det också att dölja funktionsargumentet när det passerar genom de andra dekoratörerna:@sensitive_variables("user", "pw", "cc") @some_decorator @another_decorator def process_info(user): ...
- sensitive_post_parameters(*parameters)[source]¶
Om en av dina vyer tar emot ett
HttpRequest
-objekt medPOST parameters
som kan innehålla känslig information, kan du förhindra att värdena för dessa parametrar inkluderas i felrapporterna med hjälp av dekoratornsensitive_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"], ) ...
I exemplet ovan kommer värdena för POST-parametrarna
pass_word
ochcredit_card_number
att döljas och ersättas med stjärnor (**********
) i framställningen av begäran i felrapporterna, medan värdet för parameternname
kommer att avslöjas.För att systematiskt dölja alla POST-parametrar i en begäran i felrapporter, ange inte något argument till dekoratorn
sensitive_post_parameters
:@sensitive_post_parameters() def my_view(request): ...
Alla POST-parametrar filtreras systematiskt bort från felrapporter för vissa
django.contrib.auth.views
-vyer (login
,password_reset_confirm
,password_change
ochadd_view
ochuser_change_password
iauth
-admin) för att förhindra läckage av känslig information som användarlösenord.
Anpassade felrapporter¶
Allt sensitive_variables()
och sensitive_post_parameters()
gör är att annotera den dekorerade funktionen med namnen på känsliga variabler och annotera HttpRequest
-objektet med namnen på känsliga POST-parametrar, så att denna känsliga information senare kan filtreras bort från rapporter när ett fel inträffar. Den faktiska filtreringen görs av Djangos standardfilter för felrapporter: django.views.debug.SafeExceptionReporterFilter
. Detta filter använder dekoratörernas anteckningar för att ersätta motsvarande värden med stjärnor (**********
) när felrapporterna produceras. Om du vill åsidosätta eller anpassa detta standardbeteende för hela din webbplats måste du definiera din egen filterklass och berätta för Django att använda den via inställningen DEFAULT_EXCEPTION_REPORTER_FILTER
:
DEFAULT_EXCEPTION_REPORTER_FILTER = "path.to.your.CustomExceptionReporterFilter"
Du kan också styra på ett mer detaljerat sätt vilket filter som ska användas i en viss vy genom att ställa in HttpRequest
’s exception_reporter_filter
attribut:
def my_view(request):
if request.user.is_authenticated:
request.exception_reporter_filter = CustomExceptionReporterFilter()
...
Din anpassade filterklass måste ärva från django.views.debug.SafeExceptionReporterFilter
och kan åsidosätta följande attribut och metoder:
- class SafeExceptionReporterFilter[source]¶
- cleansed_substitute¶
Strängvärdet att ersätta känsligt värde med. Som standard ersätts värdena för känsliga variabler med stjärnor (
**********
).
Ett kompilerat objekt för reguljära uttryck som används för att matcha inställningar och
request.META
-värden som anses vara känsliga. Som standard likvärdigt med:import re re.compile(r"API|AUTH|TOKEN|KEY|SECRET|PASS|SIGNATURE|HTTP_COOKIE", flags=re.IGNORECASE)
Changed in Django 5.2:Termen ”AUTH” lades till.
- is_active(request)[source]¶
Returnerar
True
för att aktivera filtreringen iget_post_parameters()
ochget_traceback_frame_variables()
. Som standard är filtret aktivt omDEBUG
ärFalse
. Observera att känsligarequest.META
-värden alltid filtreras tillsammans med känsliga inställningsvärden, vilket beskrivs iDEBUG
-dokumentationen.
- get_post_parameters(request)[source]¶
Returnerar den filtrerade ordlistan med POST-parametrar. Känsliga värden ersätts med
cleansed_substitute
.
- get_traceback_frame_variables(request, tb_frame)[source]¶
Returnerar den filtrerade ordlistan med lokala variabler för den angivna spårningsramen. Känsliga värden ersätts med
cleansed_substitute
.
Om du behöver anpassa felrapporter utöver filtreringen kan du ange en anpassad felrapportörsklass genom att definiera inställningen DEFAULT_EXCEPTION_REPORTER
:
DEFAULT_EXCEPTION_REPORTER = "path.to.your.CustomExceptionReporter"
Undantagsrapportören ansvarar för att sammanställa data för undantagsrapporten och formatera den som text eller HTML på lämpligt sätt. (Undantagsrapportören använder DEFAULT_EXCEPTION_REPORTER_FILTER
när han förbereder data för undantagsrapporten)
Din anpassade reporterklass måste ärva från django.views.debug.ExceptionReporter
.
- class ExceptionReporter[source]¶
- html_template_path[source]¶
Egenskap som returnerar en
pathlib.Path
som representerar den absoluta filsystemssökvägen till en mall för rendering av HTML-representationen av undantaget. Standard är den mall som tillhandahålls av Django.
- text_template_path[source]¶
Egenskap som returnerar en
pathlib.Path
som representerar den absoluta filsystemssökvägen till en mall för rendering av klartextrepresentationen av undantaget. Standard är den mall som tillhandahålls av Django.
- get_traceback_data()[source]¶
Returnerar en ordbok som innehåller spårningsinformation.
Detta är den huvudsakliga förlängningspunkten för att anpassa undantagsrapporter, till exempel:
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
Precis som med filterklassen kan du styra vilken klass för undantagsrapportering som ska användas i en viss vy genom att ställa in attributet exception_reporter_class
i HttpRequest
:
def my_view(request):
if request.user.is_authenticated:
request.exception_reporter_class = CustomExceptionReporter()
...
Se även
Du kan också ställa in anpassad felrapportering genom att skriva en anpassad del av exception middleware. Om du skriver anpassad felhantering är det en bra idé att efterlikna Djangos inbyggda felhantering och endast rapportera/logga fel om DEBUG
är False
.