def process_exception(self, request, exception): if (not getattr(self, 'errormator_client') or not self.errormator_client.config.get('enabled')): return None request.__e_processed_exception__ = True environ = request.environ user = getattr(request, 'user', None) if user and user.is_authenticated(): environ['errormator.username'] = unicode(user.pk) if isinstance(exception, Http404): http_status = 404 else: http_status = 500 request.__traceback__ = get_current_traceback( skip=1, show_hidden_frames=True, ignore_system_exceptions=True) # report 500's and 404's if not self.errormator_client.config['report_errors']: return None errormator_storage = get_local_storage(local_timing) stats, slow_calls = errormator_storage.get_thread_stats() self.errormator_client.py_report(environ, request.__traceback__, message=None, http_status=http_status, start_time=datetime.utcfromtimestamp( request.__start_time__), request_stats=stats) if request.__traceback__: # dereference tb object but set it to true afterwards for # other stuff del request.__traceback__ request.__traceback__ = True
def gather_data(client, environ, gather_exception=True, gather_slowness=True, gather_logs=True, clear_storage=True, exc_info=None, spawn_thread=True): if client.config['enabled'] == False: return None if not environ.get('wsgi.url_scheme'): environ['wsgi.url_scheme'] = '' if not environ.get('HTTP_HOST'): environ['HTTP_HOST'] = 'localhost' if not environ.get('errormator.request_id'): environ['errormator.request_id'] = str(uuid.uuid4()) if gather_exception and not exc_info: traceback = get_current_traceback(skip=1, show_hidden_frames=True, ignore_system_exceptions=True) elif exc_info: traceback = Traceback(*exc_info) else: traceback = None errormator_storage = get_local_storage(local_timing) stats, slow_calls = errormator_storage.get_thread_stats() if traceback: client.py_report(environ, traceback, http_status=500, request_stats=stats) # dereference del traceback traceback = True # report slowness now = datetime.datetime.utcnow() if clear_storage: errormator_storage.clear() if client.config['slow_requests'] and gather_slowness: # do we have slow calls ? if (slow_calls): client.py_slow_report(environ, now, now, slow_calls, request_stats=stats) # force log fetching traceback = True if client.config['logging'] and gather_logs: records = client.log_handler.get_records() client.log_handler.clear_records() client.py_log(environ, records=records, traceback=traceback, r_uuid=environ['errormator.request_id']) # send all data we gathered immediately at the end of request client.check_if_deliver(client.config['force_send'] or environ.get('errormator.force_send'), spawn_thread=spawn_thread)
def error_tween(request): try: response = handler(request) except blacklist as e: raise except: if 'errormator.client' in request.environ: # pass the traceback object to middleware request.environ[ 'errormator.__traceback'] = get_current_traceback( skip=1, show_hidden_frames=True, ignore_system_exceptions=True) raise return response
def test_py_report_500_traceback(self): self.setUpClient() try: raise Exception('Test Exception') except: traceback = get_current_traceback(skip=1, show_hidden_frames=True, ignore_system_exceptions=True) self.client.py_report(TEST_ENVIRON, traceback=traceback, http_status=500) self.client.report_queue[0]['traceback'] = \ 'Traceback (most recent call last):' line_no = self.client.report_queue[0]['report_details'][0]['frameinfo'][0]['line'] assert int(line_no) > 0 # set line number to match as this will change over time PARSED_REPORT_500['report_details'][0]['frameinfo'][0]['line'] = line_no self.assertEqual(self.client.report_queue[0], PARSED_REPORT_500)
def test_py_report_500_traceback(self): self.setUpClient() try: raise Exception('Test Exception') except: traceback = get_current_traceback(skip=1, show_hidden_frames=True, ignore_system_exceptions=True) self.client.py_report(TEST_ENVIRON, traceback=traceback, http_status=500) self.client.report_queue[0]['traceback'] = \ 'Traceback (most recent call last):' line_no = self.client.report_queue[0]['report_details'][0]['frameinfo'][0]['line'] assert int(line_no) > 0 # set line number to match as this will change over time PARSED_REPORT_500['report_details'][0]['frameinfo'][0]['line'] = line_no self.assertDictContainsSubset(PARSED_REPORT_500, self.client.report_queue[0])
def test_frameinfo(self): self.setUpClient(config={'errormator.report_local_vars': 'true'}) test = 1 b = {1: 'a', '2': 2, 'ccc': 'ddd'} obj = object() e_obj = client.Client({}) unic = 'grzegżółka' a_list = [1, 2, 4, 5, 6, client.Client({}), 'dupa'] long_val = 'imlong' * 100 datetest = datetime.datetime.utcnow() try: raise Exception('Test Exception') except: traceback = get_current_traceback(skip=1, show_hidden_frames=True, ignore_system_exceptions=True) self.client.py_report(TEST_ENVIRON, traceback=traceback, http_status=500) assert len( self.client.report_queue[0]['report_details'][0]['frameinfo'][0][ 'vars']) == 9
def process_exception(self, request, exception): if (not getattr(self, 'errormator_client') or not self.errormator_client.config.get('enabled')): return None request.__e_processed_exception__ = True environ = request.environ user = getattr(request, 'user', None) if user: environ['errormator.username'] = unicode(user.id) if isinstance(exception, Http404): http_status = 404 else: http_status = 500 request.__traceback__ = get_current_traceback( skip=1, show_hidden_frames=True, ignore_system_exceptions=True) # report 500's and 404's if not self.errormator_client.config['report_errors']: return None errormator_storage = get_local_storage(local_timing) stats, slow_calls = errormator_storage.get_thread_stats() self.errormator_client.py_report( environ, request.__traceback__, message=None, http_status=http_status, start_time=datetime.utcfromtimestamp(request.__start_time__), request_stats=stats) if request.__traceback__: # dereference tb object but set it to true afterwards for # other stuff del request.__traceback__ request.__traceback__ = True
def __call__(self, environ, start_response): """Run the application and conserve the traceback frames. also determine if we got 404 """ environ['errormator.request_id'] = str(uuid.uuid4()) app_iter = None detected_data = [] traceback = None start_time = default_timer() def detect_headers(status, headers, *k, **kw): detected_data[:] = status[:3], headers return start_response(status, headers, *k, **kw) # inject client instance reference to environ if 'errormator.client' not in environ: environ['errormator.client'] = self.errormator_client # some bw. compat stubs def local_report(message, include_traceback=True, http_status=200): environ['errormator.force_send'] = True def local_log(level, message): environ['errormator.force_send'] = True environ['errormator.report'] = local_report environ['errormator.log'] = local_log try: app_iter = self.app(environ, detect_headers) return app_iter except Exception as exc: if hasattr(app_iter, 'close'): app_iter.close() # we need that here traceback = get_current_traceback(skip=1, show_hidden_frames=True, ignore_system_exceptions=True) # by default reraise exceptions for app/FW to handle if self.errormator_client.config['reraise_exceptions']: raise try: start_response('500 INTERNAL SERVER ERROR', [('Content-Type', 'text/html; charset=utf-8')]) except Exception as exc: environ['wsgi.errors'].write( 'ErrormatorWSGIWrapper middleware catched exception ' 'in streamed response at a point where response headers ' 'were already sent.\n') else: return 'Server Error' finally: # report 500's and 404's # report slowness end_time = default_timer() errormator_storage = get_local_storage(local_timing) errormator_storage.thread_stats['main'] = end_time - start_time stats, slow_calls = errormator_storage.get_thread_stats() errormator_storage.clear() if 'errormator.__traceback' in environ: # get traceback gathered by tween traceback = environ['errormator.__traceback'] del environ['errormator.__traceback'] if traceback and self.errormator_client.config['report_errors']: http_status = 500 elif (self.errormator_client.config['report_404'] and detected_data and detected_data[0] == '404'): http_status = int(detected_data[0]) else: http_status = None if http_status: self.errormator_client.py_report( environ, traceback, message=None, http_status=http_status, start_time=datetime.datetime.utcfromtimestamp( start_time), request_stats=stats) # dereference del traceback traceback = True delta = datetime.timedelta(seconds=(end_time - start_time)) self.errormator_client.save_request_stats(stats) if self.errormator_client.config['slow_requests']: # do we have slow calls ? if (delta >= self.errormator_client.config['slow_request_time'] or slow_calls): self.errormator_client.py_slow_report( environ, datetime.datetime.utcfromtimestamp(start_time), datetime.datetime.utcfromtimestamp(end_time), slow_calls, request_stats=stats) # force log fetching traceback = True if self.errormator_client.config['logging']: records = self.errormator_client.log_handler.get_records() self.errormator_client.log_handler.clear_records() self.errormator_client.py_log( environ, records=records, r_uuid=environ[ 'errormator.request_id'], traceback=traceback) # send all data we gathered immediately at the end of request self.errormator_client.check_if_deliver( self.errormator_client.config['force_send'] or environ.get('errormator.force_send'))