From b0670ea164c23535970d885e078d51719c9db030 Mon Sep 17 00:00:00 2001 From: veris-neerajdhiman Date: Mon, 4 Sep 2017 15:48:09 +0530 Subject: [PATCH 1/2] Fix: middleware supoort enabled --- rest_framework_tracking/mixins.py | 45 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/rest_framework_tracking/mixins.py b/rest_framework_tracking/mixins.py index 185b803..b5da67c 100644 --- a/rest_framework_tracking/mixins.py +++ b/rest_framework_tracking/mixins.py @@ -10,6 +10,7 @@ class BaseLoggingMixin(object): """Mixin to log requests""" def initial(self, request, *args, **kwargs): # get IP + ipaddr = request.META.get("HTTP_X_FORWARDED_FOR", None) if ipaddr: # X_FORWARDED_FOR returns client1, proxy1, proxy2,... @@ -34,7 +35,9 @@ def initial(self, request, *args, **kwargs): view_method = method.lower() # create log - self.request.log = APIRequestLog( + qm = self._clean_data(request.query_params.dict()) + + self.log = APIRequestLog( requested_at=now(), path=request.path, view=view_name, @@ -42,17 +45,18 @@ def initial(self, request, *args, **kwargs): remote_addr=ipaddr, host=request.get_host(), method=request.method, - query_params=self._clean_data(request.query_params.dict()), + query_params=qm, ) # regular initial, including auth check - super(BaseLoggingMixin, self).initial(request, *args, **kwargs) + if kwargs.get('middleware') is not True: + super(BaseLoggingMixin, self).initial(request, *args, **kwargs) # add user to log after auth user = request.user if user.is_anonymous(): user = None - self.request.log.user = user + self.log.user = user # get data dict try: @@ -60,40 +64,39 @@ def initial(self, request, *args, **kwargs): # ParseError and UnsupportedMediaType exceptions. It's important not to swallow these, # as (depending on implementation details) they may only get raised this once, and # DRF logic needs them to be raised by the view for error handling to work correctly. - self.request.log.data = self._clean_data(self.request.data.dict()) + self.log.data = self._clean_data(request.data.dict()) except AttributeError: # if already a dict, can't dictify - self.request.log.data = self._clean_data(self.request.data) - - def handle_exception(self, exc): - # basic handling - response = super(BaseLoggingMixin, self).handle_exception(exc) + self.log.data = self._clean_data(request.data) + def handle_exception(self, exc, **kwargs): # log error - if hasattr(self.request, 'log'): - self.request.log.errors = traceback.format_exc() + if hasattr(self, 'log'): + self.log.errors = traceback.format_exc() - # return - return response + # basic handling + if kwargs.get('middleware') is not True: + return super(BaseLoggingMixin, self).handle_exception(exc) def finalize_response(self, request, response, *args, **kwargs): # regular finalize response - response = super(BaseLoggingMixin, self).finalize_response(request, response, *args, **kwargs) + if kwargs.get('middleware') is not True: + response = super(BaseLoggingMixin, self).finalize_response(request, response, *args, **kwargs) # check if request is being logged - if not hasattr(self.request, 'log'): + if not hasattr(self, 'log'): return response # compute response time - response_timedelta = now() - self.request.log.requested_at + response_timedelta = now() - self.log.requested_at response_ms = int(response_timedelta.total_seconds() * 1000) # save to log if (self._should_log(request, response)): - self.request.log.response = response.rendered_content - self.request.log.status_code = response.status_code - self.request.log.response_ms = response_ms + self.log.response = response.rendered_content + self.log.status_code = response.status_code + self.log.response_ms = response_ms try: - self.request.log.save() + self.log.save() except Exception: # ensure that a DB error doesn't prevent API call to continue as expected pass From 89743c530a562ab144f92a4007462fd6b4edf466 Mon Sep 17 00:00:00 2001 From: veris-neerajdhiman Date: Mon, 4 Sep 2017 15:51:42 +0530 Subject: [PATCH 2/2] DRF middleware added --- rest_framework_tracking/middleware.py | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 rest_framework_tracking/middleware.py diff --git a/rest_framework_tracking/middleware.py b/rest_framework_tracking/middleware.py new file mode 100644 index 0000000..cf7e21b --- /dev/null +++ b/rest_framework_tracking/middleware.py @@ -0,0 +1,49 @@ + +from django.utils.deprecation import MiddlewareMixin +from .mixins import LoggingMixin + + +from rest_framework.views import APIView + + +class DrfTrackingMiddleware(MiddlewareMixin): + """Log Every Activity of every Request + + """ + drf_logging = LoggingMixin() + + def _convert_django_request_to_drf_request_object(self, request): + """convert Django `httpRequest` object into DRF request object + + :param request: Django Http Request Object + :return: DRF request object + """ + return APIView().initialize_request(request) + + def process_request(self, request): + # Don;t log in case of superuser + if request.user.is_superuser: + return + rq = self._convert_django_request_to_drf_request_object(request) + self.drf_logging.initial(rq, middleware=True) + + def process_exception(self, request, exception, *args, **kwargs): + """ + """ + # Don;t log in case of superuser + + if request.user.is_superuser: + return exception + rq = self._convert_django_request_to_drf_request_object(request) + + self.drf_logging.handle_excption(rq, exception, middleware=True) + return exception + + def process_response(self, request, response): + # Don;t log in case of superuser + if request.user.is_superuser: + return response + + rq = self._convert_django_request_to_drf_request_object(request) + self.drf_logging.finalize_response(rq, response, middleware=True) + return response