Commits

Anonymous committed 403895f

Rework exception handling so that enable_logging works on exceptions even when wrappers like django-piston catch the exceptions before they hit the middleware layer.

  • Participants
  • Parent commits e23b4ff

Comments (0)

Files changed (2)

requestlog/middleware.py

 import time
 import logging
+import traceback
+import sys
 
 try:
     import json
 from requestlog import handler, models
 
 LOGGING_ENABLE_ATTR = 'LOGGING_ENABLE'
+LOGGING_EXCEPTION = 'LOGGING_EXCEPTION'
 LOGGING_START_TIME_ATTR = 'LOGGING_START_TIME'
 
 class LoggingMiddleware(object):
         logging.root.setLevel(logging.NOTSET)
         logging.root.addHandler(self._handler)
 
-    def process_exception(self, request, exception):
-        logging.error("An unhandled exception occurred: %s" % repr(exception))
+    def report_exception(exception_type=None, exception=None, tb=None):
+        if exception and exception_type and tb:
+            logging.debug("An unhandled exception occured: %s" %
+                          repr(traceback.format_exception(exception_type,
+                                                          exception, tb)))
+        elif exception:
+            logging.error("An unhandled exception occurred: %s" % repr(exception))
+
+    def log_records(self, request):
         time_taken = -1
         if hasattr(request, LOGGING_START_TIME_ATTR):
             start = getattr(request, LOGGING_START_TIME_ATTR)
                                       duration=time_taken)
         log_entry.save()
 
+    def process_exception(self, request, exception):
+        exception_type, exception, tb = sys.exc_info()
+        self.report_exception(exception=exception,
+                              exception_type=exception_type,
+                              tb=tb)
+        self.log_records(request)
+
     def process_request(self, request):
         setattr(request, LOGGING_START_TIME_ATTR, time.time())
         self._handler.clear_records()
         if not hasattr(request, LOGGING_ENABLE_ATTR):
             return response
 
-        time_taken = -1
-        if hasattr(request, LOGGING_START_TIME_ATTR):
-            start = getattr(request, LOGGING_START_TIME_ATTR)
-            time_taken = time.time() - start
-
-        records = self._handler.get_records()
-        first = records[0] if len(records) > 0 else None
-        records = [self._record_to_json(record, first) for record in records]
-        message = json.dumps(records)
-
-        log_entry = models.RequestLog(uri=request.path,
-                                      message = message,
-                                      duration=time_taken)
-        log_entry.save()
+        # Sometimes an exception will not be propagated so someone downstream
+        # can set the exception as a property on the request to make sure we
+        # note it.
+        if hasattr(request, LOGGING_EXCEPTION):
+            exception_type, exception, tb = getattr(request, LOGGING_EXCEPTION)
+            self.report_exception(exception_type=exception_type,
+                                  exception=exception,
+                                  tb=tb)
+        self.log_records(request)
 
         return response

requestlog/util.py

+import sys
 import logging
 
 from requestlog import middleware
         def new_f(*args, **kwargs):
             request = args[request_arg]
             setattr(request, middleware.LOGGING_ENABLE_ATTR, True)
-            return f(*args, **kwargs)
+            try:
+                return f(*args, **kwargs)
+            except Exception, e:
+                setattr(request,
+                        middleware.LOGGING_EXCEPTION,
+                        sys.exc_info())
+                raise e
         if hasattr(f, 'func_name'):
             new_f.func_name = f.func_name
         return new_f
     def new_f(*args, **kwargs):
         request = args[0]
         setattr(request, middleware.LOGGING_ENABLE_ATTR, True)
-        return f(*args, **kwargs)
+        try:
+            return f(*args, **kwargs)
+        except Exception, e:
+            setattr(request,
+                    middleware.LOGGING_EXCEPTION,
+                    sys.exc_info())
+            raise e
     if hasattr(f, 'func_name'):
         new_f.func_name = f.func_name
     return new_f