Example #1
0
def report_exception(exc, env=None, extra=None):
    if extra is None:
        extra = {}
    formatted = format_exception(exc, env, extra)

    if isinstance(exc, tuple):
        'pick an exception from the tuple (type, value, traceback)'
        exc = exc[1]
    if not get_config('NOODLES_SEND_FULL_MAIL'):
        send_email(repr(exc), formatted, with_hostname=True, is_html=False)
        return
    subject = repr(exc)
    report = ''
    try:
        subject = repr(exc)
        report = _collect(exc)
        report = HTMLFormatter().format(report, maxdepth=4)
    except exceptions.MakoException:
        error = exceptions.text_error_template().render()
        formatted += '\nTemplate rendering error ' + error
        log.error(error)
    attachments = None
    if report:
        attachments = {
            'report.html': report,
        }
    send_email(subject,
               formatted,
               with_hostname=True,
               attachments=attachments,
               is_html=False)
Example #2
0
 def run_callback(self, obj, args=None):
     try:
         assert hasattr(self, 'on%s' % obj)
         f = getattr(self, 'on%s' % obj)
         if args is not None:
             return f(args)
         else:
             return f()
     except WebSocketError as e:
         if is_ws_error_abnormal(e):
             log.warn('WebSocket fault: %s' % e.message)
             log.error(format_exception(e, None),
                       extra=self.channel_history)
             report_exception(e, extra=self.channel_history)
     except Exception as e:
         self.onerror(e)
         if not self.ws.closed:
             try:
                 self.ws.close()
             except WebSocketError as e:
                 if is_ws_error_abnormal(e):
                     log.error('WebSocket fault: %s' % e.message,
                               extra=self.channel_history)
     finally:
         if USE_ALCHEMY_MW:
             session_handler.close()
 def onerror(self, e):
     """Send here Exception and traceback by Error channel
     """
     f = Formatter()
     history = json.dumps(self.channel_history,
                          indent=2,
                          default=datahandler)
     data = (history, xml_escape(f.formatException(sys.exc_info())),)
     if EXCEPTION_FLAVOR == 'html':
         traceback = '<pre>%s\n\n%s</pre>' % data
     else:
         traceback = '%s\n%s' % data
     if DEBUG:
         err_message = {'channel': WS_CHANNELS['ERROR_CHID'],
                        'pkg': {'exception': repr(e), 'tb': traceback}}
     else:
         err_message = {'channel': WS_CHANNELS['ERROR_CHID'],
                        'pkg': {'exception': 'error 500',
                                'tb': 'an error occurred'}}
     log.error(format_exception(e, None), extra=self.channel_history)
     report_exception(e, extra=self.channel_history)
     if not self.ws.closed:
         try:
             self.ws.send(json.dumps(err_message, separators=(', ', ':')))
         except WebSocketError as e:
             if is_ws_error_abnormal(e):
                 log.error('WebSocket fault: %s' % e.message,
                           extra=self.channel_history)
 def run_callback(self, obj, args=None):
     try:
         assert hasattr(self, 'on%s' % obj)
         f = getattr(self, 'on%s' % obj)
         if args is not None:
             return f(args)
         else:
             return f()
     except WebSocketError as e:
         if is_ws_error_abnormal(e):
             log.warn('WebSocket fault: %s' % e.message)
             log.error(format_exception(e, None),
                       extra=self.channel_history)
             report_exception(e, extra=self.channel_history)
     except Exception as e:
         self.onerror(e)
         if not self.ws.closed:
             try:
                 self.ws.close()
             except WebSocketError as e:
                 if is_ws_error_abnormal(e):
                     log.error('WebSocket fault: %s' % e.message,
                               extra=self.channel_history)
     finally:
         if USE_ALCHEMY_MW:
             session_handler.close()
Example #5
0
 def __call__(self):
     try:
         return self.callable()
     except Exception as e:
         log.error(format_exception(e, None))
         report_exception(e)
         data = {'error': 0, 'message': e.message}
         return XResponse(data)
 def safe_exec(self, fn):
     """
     Must never fall
     """
     try:
         fn()
     except Exception as e:
         log.error(e)
 def channel_404(self, channel):
     try:
         return self.ws.send(json.dumps({'channel': channel,
                                         'action': 'no-such-channel',
                                         'note': 'Channel with ID=%s not '
                                                 'found' % channel,
                                         }))
     except WebSocketError as e:
         if is_ws_error_abnormal(e):
             log.error('WebSocket fault: %s' % e.message,
                       extra=self.channel_history)
def noodlesapp(env, start_response):
    """

    :rtype : noodles.http.Response
    :param env:
    :param start_response:
    :return: :rtype: :raise:
    """
    # Get request object
    if get_config('ENCODE_SEMICOLON_IN_REQUEST') is True:
        env['QUERY_STRING'] = re.sub('[;]', '%3b', env['QUERY_STRING'])
    request = Request(env)

    if "HTTP_X_FORWARDED_FOR" in env:
        x_forwarded_for = env["HTTP_X_FORWARDED_FOR"].split(',')[:1]
        if x_forwarded_for:
            request.remote_addr = x_forwarded_for[0]
    #print("Try to handle url_path '%s'" % request.path)
    # Get callable object with routine method to handle request
    producer = dispatcher.get_callable(request)
    if not producer:
        # May be here an error,raise exception
        raise Exception('Can\'t find callable for this url path')

    # Callable function must return Response object
    try:
        response = middlewares.run_chain(producer, request)
        if not hasattr(response, 'is_noodles_response'):
            response = producer()
    # Capture traceback here and send it if debug mode
    except Exception as e:
        f = Formatter()
        if EXCEPTION_FLAVOR=='html':
            traceback = '<pre>%s\n\n%s</pre>' \
                        % (json.dumps(env, indent=2, default=datahandler),
                           xml_escape(f.formatException(sys.exc_info())))
        else:
            traceback = '%s\n%s' \
                        % (json.dumps(env, indent=2, default=datahandler),
                           f.formatException(sys.exc_info()))
        extra = {'request': request}
        log.error(format_exception(e, None), extra=extra)
        report_exception(e, extra=extra)

        if DEBUG:
            response = Error500(e, traceback)
        else:
            response = Error500()
    finally:
        middlewares.end_chain(lambda x: x, request)

    return response(env, start_response)
Example #9
0
def noodlesapp(env, start_response):
    """

    :rtype : noodles.http.Response
    :param env:
    :param start_response:
    :return: :rtype: :raise:
    """
    # Get request object
    if get_config('ENCODE_SEMICOLON_IN_REQUEST') is True:
        env['QUERY_STRING'] = re.sub('[;]', '%3b', env['QUERY_STRING'])
    request = Request(env)

    if "HTTP_X_FORWARDED_FOR" in env:
        x_forwarded_for = env["HTTP_X_FORWARDED_FOR"].split(',')[:1]
        if x_forwarded_for:
            request.remote_addr = x_forwarded_for[0]
    #print("Try to handle url_path '%s'" % request.path)
    # Get callable object with routine method to handle request
    producer = dispatcher.get_callable(request)
    if not producer:
        # May be here an error,raise exception
        raise Exception('Can\'t find callable for this url path')

    # Callable function must return Response object
    try:
        response = middlewares.run_chain(producer, request)
        if not hasattr(response, 'is_noodles_response'):
            response = producer()
    # Capture traceback here and send it if debug mode
    except Exception as e:
        f = Formatter()
        if EXCEPTION_FLAVOR=='html':
            traceback = '<pre>%s\n\n%s</pre>' \
                        % (json.dumps(env, indent=2, default=datahandler),
                           xml_escape(f.formatException(sys.exc_info())))
        else:
            traceback = '%s\n%s' \
                        % (json.dumps(env, indent=2, default=datahandler),
                           f.formatException(sys.exc_info()))
        extra = {'request': request}
        log.error(format_exception(e, None), extra=extra)
        report_exception(e, extra=extra)

        if DEBUG:
            response = Error500(e, traceback)
        else:
            response = Error500()
    finally:
        middlewares.end_chain(lambda x: x, request)

    return response(env, start_response)
Example #10
0
 def channel_404(self, channel):
     try:
         return self.ws.send(
             json.dumps({
                 'channel': channel,
                 'action': 'no-such-channel',
                 'note': 'Channel with ID=%s not '
                 'found' % channel,
             }))
     except WebSocketError as e:
         if is_ws_error_abnormal(e):
             log.error('WebSocket fault: %s' % e.message,
                       extra=self.channel_history)
Example #11
0
def worker(n):
    cli = bernhard.Client(**RIEMANN_ARGS)
    while True:
        try:
            target, metric = RIEMANN_QUEUE.get()
            target = target.partition('?')[0]
            target = target.replace('/', '.')
            event = {'service': target, 'metric': metric}
            event.update(RIEMANN_SOURCE)
            result = cli.send(event=event)
            log.debug("Sent %s result %s", target, result)
        except Exception as e:
            log.error(e)
Example #12
0
 def __init__(self, data):
     if type(data) == dict:
         self.data = data
         return
     # TODO: check lib: https://bitbucket.org/Jeffrey/gevent-websocket/
     # issue/5/encoding-issue-when-sending-non-ascii
     self.raw_data = str(data.decode('utf-8')).encode(ENCODING)
     try:
         self.data = json.loads(self.raw_data)
     except ApiSocketError as e:
         self.data = self.raw_data
         extra = {'request': self.data}
         log.error(format_exception(e, None), extra=extra)
         report_exception(e, extra=extra)
 def send_error_code(self, code, act, channel):
     if not self.ws.closed:
         try:
             self.ws.send(json.dumps({'pkg': {'action': act,
                                      'data': {'channel': channel,
                                               'result': code,
                                               },
                                              },
                                      }))
             self.ws.close()
         except WebSocketError as e:
             if is_ws_error_abnormal(e):
                 log.error('WebSocket fault: %s' % e.message,
                           extra=self.channel_history)
 def bad_request(self, message="Bad request"):
     if not self.ws.closed:
         try:
             self.ws.send(
                 json.dumps({'pkg': {'action': 'open',
                                     'data': {'result': 400,
                                              'message': message,
                                              },
                                     },
                             }))
         except WebSocketError as e:
             if is_ws_error_abnormal(e):
                 log.error('WebSocket fault: %s' % e.message,
                           extra=self.channel_history)
 def __init__(self, data):
     if type(data) == dict:
         self.data = data
         return
     # TODO: check lib: https://bitbucket.org/Jeffrey/gevent-websocket/
     # issue/5/encoding-issue-when-sending-non-ascii
     self.raw_data = str(data.decode('utf-8')).encode(ENCODING)
     try:
         self.data = json.loads(self.raw_data)
     except ApiSocketError as e:
         self.data = self.raw_data
         extra = {'request': self.data}
         log.error(format_exception(e, None), extra=extra)
         report_exception(e, extra=extra)
def worker(n):
    cli = bernhard.Client(**RIEMANN_ARGS)
    while True:
        try:
            target, metric = RIEMANN_QUEUE.get()
            target = target.partition('?')[0]
            target = target.replace('/', '.')
            event = {'service': target,
                     'metric': metric}
            event.update(RIEMANN_SOURCE)
            result = cli.send(event=event)
            log.debug("Sent %s result %s", target, result)
        except Exception as e:
            log.error(e)
Example #17
0
    def close(self, data):
        if not data.get('channel'):
            raise Exception('No channel name, exit')

        handler = self.channel_handlers.get(data['channel'])

        if not handler:
            return self.channel_404(data['channel'])

        if self.check_permissions and not self.validate_close(data['channel']):
            return self.send_error_code(403, 'open', data['channel'])

        if not handler.closable and not self.ws.closed:
            try:
                self.ws.send(
                    json.dumps({
                        'pkg': {
                            'action': 'close',
                            'data': {
                                'channel': data['channel'],
                                'result': 501
                            },
                        },
                    }))
            except WebSocketError as e:
                if is_ws_error_abnormal(e):
                    log.error('WebSocket fault: %s' % e.message,
                              extra=self.channel_history)
            return

        handler.onclose()
        del self.channel_handlers[data['channel']]

        if not self.ws.closed:
            try:
                self.ws.send(
                    json.dumps({
                        'pkg': {
                            'action': 'close',
                            'data': {
                                'channel': data['channel'],
                                'result': 200
                            },
                        },
                    }))
            except WebSocketError as e:
                if is_ws_error_abnormal(e):
                    log.error('WebSocket fault: %s' % e.message,
                              extra=self.channel_history)
 def _send_ws(self, data):
     if type(data) != dict:
         raise TypeError("data is %s not dict" % type(data))
     package_to_send = {'channel': self.channel,
                        'pkg': data,
                        'session_params': self.session.params,
                        }
     data = json.dumps(package_to_send, default=datahandler)
     try:
         self.ws.send(data)
     except WebSocketError as e:
         if is_ws_error_abnormal(e):
             log.error('WebSocket fault: %s' % e.message,
                       extra=self.channel_history)
         self.onclose()
Example #19
0
 def _send_ws(self, data):
     if type(data) != dict:
         raise TypeError("data is %s not dict" % type(data))
     package_to_send = {
         'channel': self.channel,
         'pkg': data,
         'session_params': self.session.params,
     }
     data = json.dumps(package_to_send, default=datahandler)
     try:
         self.ws.send(data)
     except WebSocketError as e:
         if is_ws_error_abnormal(e):
             log.error('WebSocket fault: %s' % e.message,
                       extra=self.channel_history)
         self.onclose()
Example #20
0
 def bad_request(self, message="Bad request"):
     if not self.ws.closed:
         try:
             self.ws.send(
                 json.dumps({
                     'pkg': {
                         'action': 'open',
                         'data': {
                             'result': 400,
                             'message': message,
                         },
                     },
                 }))
         except WebSocketError as e:
             if is_ws_error_abnormal(e):
                 log.error('WebSocket fault: %s' % e.message,
                           extra=self.channel_history)
Example #21
0
    def open(self, data):
        self.propagate_greenlet_data(data)
        if not data.get('token'):
            self.bad_request(message='No access token, exit')
            return

        if not data.get('channel'):
            self.bad_request(message='No channel name')
            return

        self.access_token = data.get('token')
        self.reopen = data.get('reopen', False)
        self.pre_open()
        handler = self.allowed_channels.get(data.get('channel'))
        if not handler:
            return self.channel_404(data['channel'])

        if self.check_permissions \
                and not self.validate_open(data.get('channel')):
            return self.send_error_code(403, 'open', data.get('channel'))
        if not self.is_auth:
            return self.send_error_code(403, 'open', data.get('channel'))

        handler = self.register_channel(data.get('channel'), handler)
        self.run_callback('open')
        pkg = {
            'action': 'open',
            'data': {
                'closable': handler.closable,
                'result': 200
            },
        }
        package_to_send = {
            'channel': data.get('channel'),
            'pkg': pkg,
            'session_params': self.session.params
        }
        raw_data = json.dumps(package_to_send, default=datahandler)
        self.after_open()
        try:
            self.ws.send(raw_data)
        except WebSocketError as e:
            if is_ws_error_abnormal(e):
                log.error('WebSocket fault: %s' % e.message,
                          extra=self.channel_history)
Example #22
0
 def send_error_code(self, code, act, channel):
     if not self.ws.closed:
         try:
             self.ws.send(
                 json.dumps({
                     'pkg': {
                         'action': act,
                         'data': {
                             'channel': channel,
                             'result': code,
                         },
                     },
                 }))
             self.ws.close()
         except WebSocketError as e:
             if is_ws_error_abnormal(e):
                 log.error('WebSocket fault: %s' % e.message,
                           extra=self.channel_history)
    def close(self, data):
        if not data.get('channel'):
            raise Exception('No channel name, exit')

        handler = self.channel_handlers.get(data['channel'])

        if not handler:
            return self.channel_404(data['channel'])

        if self.check_permissions and not self.validate_close(data['channel']):
            return self.send_error_code(403, 'open', data['channel'])

        if not handler.closable and not self.ws.closed:
            try:
                self.ws.send(
                    json.dumps({'pkg': {'action': 'close',
                                        'data': {'channel': data['channel'],
                                                 'result': 501},
                                        },
                                }))
            except WebSocketError as e:
                if is_ws_error_abnormal(e):
                    log.error('WebSocket fault: %s' % e.message,
                              extra=self.channel_history)
            return

        handler.onclose()
        del self.channel_handlers[data['channel']]

        if not self.ws.closed:
            try:
                self.ws.send(
                    json.dumps({'pkg': {'action': 'close',
                                        'data': {'channel': data['channel'],
                                                 'result': 200},
                                        },
                                }))
            except WebSocketError as e:
                if is_ws_error_abnormal(e):
                    log.error('WebSocket fault: %s' % e.message,
                              extra=self.channel_history)
    def open(self, data):
        self.propagate_greenlet_data(data)
        if not data.get('token'):
            self.bad_request(message='No access token, exit')
            return

        if not data.get('channel'):
            self.bad_request(message='No channel name')
            return

        self.access_token = data.get('token')
        self.reopen = data.get('reopen', False)
        self.pre_open()
        handler = self.allowed_channels.get(data.get('channel'))
        if not handler:
            return self.channel_404(data['channel'])

        if self.check_permissions \
                and not self.validate_open(data.get('channel')):
            return self.send_error_code(403, 'open', data.get('channel'))
        if not self.is_auth:
            return self.send_error_code(403, 'open', data.get('channel'))

        handler = self.register_channel(data.get('channel'), handler)
        self.run_callback('open')
        pkg = {'action': 'open',
               'data': {'closable': handler.closable,
                        'result': 200},
               }
        package_to_send = {'channel': data.get('channel'),
                           'pkg': pkg,
                           'session_params': self.session.params}
        raw_data = json.dumps(package_to_send, default=datahandler)
        self.after_open()
        try:
            self.ws.send(raw_data)
        except WebSocketError as e:
            if is_ws_error_abnormal(e):
                log.error('WebSocket fault: %s' % e.message,
                          extra=self.channel_history)
Example #25
0
 def onerror(self, e):
     """Send here Exception and traceback by Error channel
     """
     f = Formatter()
     history = json.dumps(self.channel_history,
                          indent=2,
                          default=datahandler)
     data = (
         history,
         xml_escape(f.formatException(sys.exc_info())),
     )
     if EXCEPTION_FLAVOR == 'html':
         traceback = '<pre>%s\n\n%s</pre>' % data
     else:
         traceback = '%s\n%s' % data
     if DEBUG:
         err_message = {
             'channel': WS_CHANNELS['ERROR_CHID'],
             'pkg': {
                 'exception': repr(e),
                 'tb': traceback
             }
         }
     else:
         err_message = {
             'channel': WS_CHANNELS['ERROR_CHID'],
             'pkg': {
                 'exception': 'error 500',
                 'tb': 'an error occurred'
             }
         }
     log.error(format_exception(e, None), extra=self.channel_history)
     report_exception(e, extra=self.channel_history)
     if not self.ws.closed:
         try:
             self.ws.send(json.dumps(err_message, separators=(', ', ':')))
         except WebSocketError as e:
             if is_ws_error_abnormal(e):
                 log.error('WebSocket fault: %s' % e.message,
                           extra=self.channel_history)
Example #26
0
def basic_report_exception(exc, env=None, msg=''):
    formatted = format_exception(exc, env, msg)
    log.error(formatted)
    send_email(repr(exc), formatted, with_hostname=True, is_html=False)
    def __call__(self, env, start_response):
        websocket = env.get('wsgi.websocket')
        if not websocket:
            self.bad_request()
        self.ws = websocket
        # Endless event loop
        while 1:
            try:
                data = self.ws.receive()
                self.clear_test_data()
            except WebSocketError as e:
                if is_ws_error_abnormal(e):
                    log.error('WebSocket fault: %s' % e.message,
                              extra=self.channel_history)
                break
            except Exception:
                f = Formatter()
                traceback = f.formatException(sys.exc_info())
                log.error('Servlet fault: \n%s' % traceback,
                          extra=self.channel_history)
                break

            if data:
                jd = json.loads(data)
                if jd.get('pkg') \
                        and jd['pkg'].get('data') \
                        and isinstance(jd['pkg']['data'], dict)\
                        and jd['pkg']['data'].get('testData'):
                    self.write_test_data(jd['pkg']['data']['testData'])
                    del jd['pkg']['data']['testData']
                self.channel_history['messages'].append(jd)
                if hasattr(self.session, 'sess') and self.session.sess:
                    self.channel_history['session_id'] = self.session.sess.id
                    self.channel_history['user_id'] = self.session.sess.user_id
                if not jd.get('channel') and jd.get('pkg'):
                    act = jd['pkg'].get('action')
                    assert not act.startswith('_'), "security violation"
                    try:
                        handler = getattr(self, act)
                    except WebSocketError as e:
                        if is_ws_error_abnormal(e):
                            f = Formatter()
                            traceback = f.formatException(sys.exc_info())
                            log.error('Global channel action error: \n%s'
                                      % traceback, extra=self.channel_history)
                        break
                    assert handler.__name__ == "action_wrapper", \
                        "%s is not allowed to be executed externally." % act
                    handler(jd['pkg']['data'])
                    continue
                if self.check_permissions \
                        and not self.validate_send(jd.get('channel')):
                    jd['result'] = 403
                    if not self.ws.closed:
                        try:
                            self.ws.send(json.dumps(jd))
                        except WebSocketError as e:
                            if is_ws_error_abnormal(e):
                                log.error('WebSocket fault: %s' % e.message,
                                          extra=self.channel_history)
                    continue
                else:
                    self.run_callback('message', ApiSocketMessage(data))
            else:
                log.debug('Web Socket is disconnected')
                self.close_event.set()
            if self.close_event.is_set():
                break
        self.run_callback('close')
Example #28
0
    def __call__(self, env, start_response):
        websocket = env.get('wsgi.websocket')
        if not websocket:
            self.bad_request()
        self.ws = websocket
        # Endless event loop
        while 1:
            try:
                data = self.ws.receive()
                self.clear_test_data()
            except WebSocketError as e:
                if is_ws_error_abnormal(e):
                    log.error('WebSocket fault: %s' % e.message,
                              extra=self.channel_history)
                break
            except Exception:
                f = Formatter()
                traceback = f.formatException(sys.exc_info())
                log.error('Servlet fault: \n%s' % traceback,
                          extra=self.channel_history)
                break

            if data:
                jd = json.loads(data)
                if jd.get('pkg') \
                        and jd['pkg'].get('data') \
                        and isinstance(jd['pkg']['data'], dict)\
                        and jd['pkg']['data'].get('testData'):
                    self.write_test_data(jd['pkg']['data']['testData'])
                    del jd['pkg']['data']['testData']
                self.channel_history['messages'].append(jd)
                if hasattr(self.session, 'sess') and self.session.sess:
                    self.channel_history['session_id'] = self.session.sess.id
                    self.channel_history['user_id'] = self.session.sess.user_id
                if not jd.get('channel') and jd.get('pkg'):
                    act = jd['pkg'].get('action')
                    assert not act.startswith('_'), "security violation"
                    try:
                        handler = getattr(self, act)
                    except WebSocketError as e:
                        if is_ws_error_abnormal(e):
                            f = Formatter()
                            traceback = f.formatException(sys.exc_info())
                            log.error('Global channel action error: \n%s' %
                                      traceback,
                                      extra=self.channel_history)
                        break
                    assert handler.__name__ == "action_wrapper", \
                        "%s is not allowed to be executed externally." % act
                    handler(jd['pkg']['data'])
                    continue
                if self.check_permissions \
                        and not self.validate_send(jd.get('channel')):
                    jd['result'] = 403
                    if not self.ws.closed:
                        try:
                            self.ws.send(json.dumps(jd))
                        except WebSocketError as e:
                            if is_ws_error_abnormal(e):
                                log.error('WebSocket fault: %s' % e.message,
                                          extra=self.channel_history)
                    continue
                else:
                    self.run_callback('message', ApiSocketMessage(data))
            else:
                log.debug('Web Socket is disconnected')
                self.close_event.set()
            if self.close_event.is_set():
                break
        self.run_callback('close')