Django Error Logging: Adding Request Header, Body And User Information
Solution 1:
I think a complete solution to the logging problem you have is to implement a middleware. The middleware would be able to work with any kind of view implementation you have, irrespective of whether it is a class based view, function based view or APIView from DRF.
You can define a middleware for full logging. Make sure that you place the middleware appropriately after the authentication middleware -
MIDDLEWARE = [
...,
'django.contrib.auth.middleware.AuthenticationMiddleware',
...,
'path.to.your.middleware.LogMiddleware'
]
In the log middleware, you would have access to the request and response. You can store request, the user (if authenticated) and all the META properties coming from the request via a logger, or you can even store it in a database if you want. Although, beware that storing in database comes at a cost. You can learn how to write a middleware by going through the Django middleware documentation.
import traceback
classLogMiddleware():
def__init__(self, get_response):
self.get_response = get_response
def__call__(self, request):
try:
return self.get_response(request)
except:
if request.user.is_authenticated():
# Log the user
path = request.get_full_path() # Get the URL Path
tb = traceback.format_exc() # Get the traceback
meta = request.META # Get request meta information# Log everythingraise# Raise exception again after catchingYou can read about all the meta attributes present from the django documentation of HttpRequest. Let me know if you need any clarification on this.
Solution 2:
I would use a decorator here. Cut straight to the code...
import logging
from functools import wraps
from django.http import HttpResponse, HttpRequest
logging.basicConfig(filename="errors.log",
level=logging.ERROR,
format='%(asctime)s: %(message)s')
log = logging.getLogger(__name__)
deflog_exceptions(wrapped):
@wraps(wrapped)defwrapper(*args, **kwargs):
try:
return wrapped(*args, **kwargs)
except:
# log and re-raise
request = args[0] iflen(args) > 0andisinstance(args[0], HttpRequest) elseNone
msg = ("\nuser.id/email: {}/{}\nMETA: {}...\nbody: {}"
.format(request.user.id,
getattr(request.user, 'email','?'),
str(request.META)[:80],
request.body)
if request
else"not a HttpRequest")
log.exception(msg)
raisereturn wrapper
@log_exceptionsdefrandom_view(request):
raise ValueError("simulate a crash")
if request.user.is_authenticated() and request.user.is_active:
return HttpResponse('hi')
# generic view code goes here.else:
return HttpResponse(status=401)
and errors.log should capture something like
2017-06-27 20:48:09,282:
user.id/email: 1/test@domain.comMETA: {'SESSION_MANAGER': 'local/acb:@/tmp/.ICE-unix/4255,unix/acb:/tmp/.ICE-unix/4255...body: b''
Traceback (most recent call last):
File "/home/rod/pyves/rangetest/rangetest/data/views.py", line 14, in wrapper
return wrapped(*args, **kwargs)
File "/home/rod/pyves/rangetest/rangetest/data/views.py", line 31, in random_view
raise ValueError("simulate a crash")
ValueError: simulate a crashNote, you'll also probably see the Django crash logging in your errors.log as well. You might split the logs to separate files using Django's well documented, but nonetheless complex logging config
Post a Comment for "Django Error Logging: Adding Request Header, Body And User Information"