美文网首页
raven.contrib.flask.Sentry的base.

raven.contrib.flask.Sentry的base.

作者: 寺院的研究僧 | 来源:发表于2018-01-06 08:26 被阅读52次

    Flask中使用Sentry来捕获异常,通常只需要在flask的init.py最后加入如下代码即可

    
    if config.SENTRY_ENABLED:
    
       from raven.contrib.flaskimport Sentry
    
       sentry = Sentry(app, dsn='https://xxxx')
    
    

    我想看下每个event的数据是怎么封装的,于是找到了build_msg这个函数

    raven的base.py中函数build_msg

    
    def build_msg(self, event_type, data=None, date=None,
    
    time_spent=None, extra=None, stack=None, public_key=None,
    
    tags=None, fingerprint=None,**kwargs):
    
        """
    
    Captures, processes and serializes an event into a dict object
    
    The result of ``build_msg`` should be a standardized dict, with
    
    all default values available.
    
    """
    
    # create ID client-side so that it can be passed to application
    
        event_id= uuid.uuid4().hex
    
    data= merge_dicts(self.context.data, data)
    
    data.setdefault('tags', {})
    
    data.setdefault('extra', {})
    
    if '.' not in event_type:
    
            # Assume it's a builtin
    
            event_type= 'raven.events.%s' % event_type
    
    handler= self.get_handler(event_type)
    
    result= handler.capture(**kwargs)
    
    # data (explicit) culprit takes over auto event detection
    
        culprit= result.pop('culprit', None)
    
    if data.get('culprit'):
    
            culprit= data['culprit']
    
    for k, vin iteritems(result):
    
            if knot in data:
    
                data[k]= v
    
    # auto_log_stacks only applies to events that are not exceptions
    
    # due to confusion about which stack is which and the automatic
    
    # application of stacktrace to exception objects by Sentry
    
        if stackis Noneand 'exception' not in data:
    
            stack= self.auto_log_stacks
    
    if stackand 'stacktrace' not in data:
    
            if stackis True:
    
                frames= iter_stack_frames()
    
    else:
    
                frames= stack
    
    stack_info= get_stack_info(
    
    frames,
    
    transformer=self.transform,
    
    capture_locals=self.capture_locals,
    
    )
    
    data.update({
    
    'stacktrace': stack_info,
    
    })
    
    if self.include_paths:
    
            for framein self._iter_frames(data):
    
                if frame.get('in_app')is not None:
    
                    continue
    
                path= frame.get('module')
    
    if not path:
    
                    continue
    
                if path.startswith('raven.'):
    
                    frame['in_app']= False
    
    else:
    
                    frame['in_app']= (
    
    any(path.startswith(x)for xin self.include_paths)and
    
                        not any(path.startswith(x)for xin self.exclude_paths)
    
    )
    
    if not culprit:
    
            culprit= self.transaction.peek()
    
    if not data.get('level'):
    
            data['level']= kwargs.get('level')or logging.ERROR
    
    if not data.get('server_name'):
    
            data['server_name']= self.name
    
    if not data.get('modules'):
    
            data['modules']= self.get_module_versions()
    
    if self.releaseis not None:
    
            data['release']= self.release
    
    if self.environmentis not None:
    
            data['environment']= self.environment
    
    data['tags']= merge_dicts(self.tags, data['tags'], tags)
    
    data['extra']= merge_dicts(self.extra, data['extra'], extra)
    
    # Legacy support for site attribute
    
        site= data.pop('site', None)or self.site
    
    if site:
    
            data['tags'].setdefault('site', site)
    
    if culprit:
    
            data['culprit']= culprit
    
    if fingerprint:
    
            data['fingerprint']= fingerprint
    
    # Run the data through processors
    
        for processorin self.get_processors():
    
            data.update(processor.process(data))
    
    if 'message' not in data:
    
            data['message']= kwargs.get('message', handler.to_string(data))
    
    # tags should only be key=>u'value'
    
        for key, valuein iteritems(data['tags']):
    
            data['tags'][key]= to_unicode(value)
    
    # print "KV", key, value, data['tags'][key]
    
    # extra data can be any arbitrary value
    
        for k, vin iteritems(data['extra']):
    
            data['extra'][k]= self.transform(v)
    
    # It's important date is added **after** we serialize
    
        data.setdefault('project', self.remote.project)
    
    data.setdefault('timestamp', dateor datetime.utcnow())
    
    data.setdefault('time_spent', time_spent)
    
    data.setdefault('event_id', event_id)
    
    data.setdefault('platform', PLATFORM_NAME)
    
    data.setdefault('sdk', SDK_VALUE)
    
    data.setdefault('repos', self.repos)
    
    print "[TAGS]", data['tags'], data.keys()
    
    print "[VALUES]", data.values()
    
    # insert breadcrumbs
    
        if self.enable_breadcrumbs:
    
            crumbs= self.context.breadcrumbs.get_buffer()
    
    if crumbs:
    
                # Make sure we send the crumbs here as "values" as we use the
    
    # raven client internally in sentry and the alternative
    
    # submission option of a list here is not supported by the
    
    # internal sender.
    
                data.setdefault('breadcrumbs', {'values': crumbs})
    
    return data
    
    

    在代码中随便写了一个print来打印一个不存在的key来引发异常,每个event的data.values()结构有点复杂,结果如下

    
    [None, {'values': [{ 'stacktrace': {'frames': [ {'function': 'wsgi_app', 'abs_path': '/Users/charles/workspace/jiayincloud/titans/.venv/lib/python2.7/site-packages/flask/app.py', 'pre_context': [' ctx = self.request_context(environ)', ' ctx.push()', ' error = None', ' try:', ' try:' ], 'post_context': [ ' except Exception as e:', ' error = e', ' response = self.handle_exception(e)', ' except:',                                                                         ' error = sys.exc_info()[1]' ], 'vars': {'e': "KeyError('name',)", 'start_response': '', 'self': "", 'ctx': "", 'environ': {"'HTTP_CACHE_CONTROL'": "'max-age=0'", "'HTTP_UPGRADE_INSECURE_REQUESTS'": "'1'", "'wsgi.multiprocess'": True, "'HTTP_ACCEPT_ENCODING'": "'gzip, deflate, br'", "'HTTP_ACCEPT_LANGUAGE'": "'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7'", "'HTTP_ACCEPT'": "'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'", "'wsgi.multithread'": False, "'SCRIPT_NAME'": "''", "'QUERY_STRING'": "'code=2109d42687cc00d85129d795d5ad8ad905be5bc19533215be817f6b8c5783f31'", "'wsgi.input'": '<_io.BytesIO object at 0x10b4f20b0>', "'PATH_INFO'": "'/oauth/callback'", "'REQUEST_METHOD'": "'GET'", "'HTTP_USER_AGENT'": "'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36'", "'SERVER_PORT'": "'5000'", "'wsgi.url_scheme'": "'http'", "'REMOTE_ADDR'": "'127.0.0.1'", "'SERVER_PROTOCOL'": "'HTTP/1.1'", "'wsgi.version'": [1, 0], "'wsgi.errors'": "', mode 'w' at 0x10787f1e0>", "'SERVER_NAME'": "'127.0.0.1'", "'werkzeug.request'": "", "'wsgi.run_once'": False, "'HTTP_HOST'": "'127.0.0.1:5000'", "'HTTP_CONNECTION'": "'keep-alive'", "'HTTP_COOKIE'": "'session=eyJPQVVUSF9BRlRFUl9MT0dJTl9TRVNTSU9OX1VSTCI6Ii8ifQ.DTDDRg.oW8B4bGCRz1RWWo36GwLKctcHlw'"}, 'error': "KeyError('name',)"}, 'module': 'flask.app', 'filename': 'flask/app.py', 'lineno': 1982, 'in_app': False, 'context_line': ' response = self.full_dispatch_request()' }, {'function': 'full_dispatch_request', 'abs_path': '/Users/charles/workspace/jiayincloud/titans/.venv/lib/python2.7/site-packages/flask/app.py', 'pre_context': [' request_started.send(self)', ' rv = self.preprocess_request()', ' if rv is None:', ' rv = self.dispatch_request()', ' except Exception as e:'], 'post_context': [' return self.finalize_request(rv)', '', ' def finalize_request(self, rv, from_error_handler=False):', ' """Given the return value from a view function this finalizes', ' the request by converting it into a response and invoking the'], 'vars': {'rv': None, 'e': "KeyError('name',)", 'self': ""}, 'module': 'flask.app', 'filename': 'flask/app.py', 'lineno': 1614, 'in_app': False, 'context_line': ' rv = self.handle_user_exception(e)' }, {'function': 'handle_user_exception', 'abs_path': '/Users/charles/workspace/jiayincloud/titans/.venv/lib/python2.7/site-packages/flask/app.py', 'pre_context': [' return self.handle_http_exception(e)', '', ' handler = self._find_error_handler(e)', '', ' if handler is None:'], 'post_context': [' return handler(e)', '', ' def handle_exception(self, e):', ' """Default exception handling that kicks in when an exception', ' occurs that is not caught. In debug mode the exception will'], 'vars': {'e': "KeyError('name',)", 'self': "", 'exc_type': "", 'handler': None, 'tb': '', 'exc_value': "KeyError('name',)"}, 'module': 'flask.app', 'filename': 'flask/app.py', 'lineno': 1517, 'in_app': False, 'context_line': ' reraise(exc_type, exc_value, tb)' }, {'function': 'full_dispatch_request', 'abs_path': '/Users/charles/workspace/jiayincloud/titans/.venv/lib/python2.7/site-packages/flask/app.py', 'pre_context': [' self.try_trigger_before_first_request_functions()', ' try:', ' request_started.send(self)', ' rv = self.preprocess_request()', ' if rv is None:'], 'post_context': [' except Exception as e:', ' rv = self.handle_user_exception(e)', ' return self.finalize_request(rv)', '', ' def finalize_request(self, rv, from_error_handler=False):'], 'vars': {'rv': None, 'e': "KeyError('name',)", 'self': ""}, 'module': 'flask.app', 'filename': 'flask/app.py', 'lineno': 1612, 'in_app': False, 'context_line': ' rv = self.dispatch_request()' }, {'function': 'dispatch_request', 'abs_path': '/Users/charles/workspace/jiayincloud/titans/.venv/lib/python2.7/site-packages/flask/app.py', 'pre_context': [' # request came with the OPTIONS method, reply automatically', " if getattr(rule, 'provide_automatic_options', False) \\", " and req.method == 'OPTIONS':", ' return self.make_default_options_response()', ' # otherwise dispatch to the handler for that endpoint'], 'post_context': ['', ' def full_dispatch_request(self):', ' """Dispatches the request and on top of that performs request', ' pre and postprocessing as well as HTTP exception catching and', ' error handling.'], 'vars': {'self': "", 'req': "", 'rule': "gitlab.authorized>"}, 'module': 'flask.app', 'filename': 'flask/app.py', 'lineno': 1598, 'in_app': False, 'context_line': ' return self.view_functions[rule.endpoint](**req.view_args)' }, {'function': 'authorized', 'abs_path': '/Users/charles/workspace/jiayincloud/titans/titans/lib/oauth/gitlab.py', 'pre_context': ['', ' # 1. using requests method', ' s = requests.session()', " res = s.request('POST', config.GITLAB_OAUTH_ACCESS_TOKEN_URL, **payload)", ' auth = res.json()'], 'post_context': [' """', ' For Gitlab 8.14.5', " res: {u'access_token': u'ed1471bf5f6e3b7caae9f33f7c73a36d5d20b392c483adab7ca0161a496f8dd9', ", " u'token_type': u'bearer', ", " u'created_at': 1512534693, "], 'vars': {'res': '', 's': '',
    
                                                                    'payload': {"'data'": {"'client_id'": "'0e96e89b7e4c84fb066039e85aa59731e7a0dae72912f25a9af5935cdfd02d95'",
    
                                                                                            "'scope'": "'read_user'",
    
                                                                                            "'redirect_uri'": "'http://127.0.0.1:5000/oauth/callback'",
    
                                                                                            "'grant_type'": "'authorization_code'",
    
                                                                                            "'client_secret'": '********',
    
                                                                                            "'code'": u"u'2109d42687cc00d85129d795d5ad8ad905be5bc19533215be817f6b8c5783f31'"
    
                                                                                          }
    
                                                                                },
    
                                                                    'auth': {u"u'error'": u"u'invalid_grant'",
    
                                                                            u"u'error_description'": u"u'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.'"
    
                                                                            }
    
                                                                    },
    
                                                            'module': 'titans.lib.oauth.gitlab',
    
                                                            'filename': 'titans/lib/oauth/gitlab.py',
    
                                                            'lineno': 63,
    
                                                            'in_app': True,
    
                                                            'context_line': '    print auth["name"]'
    
                                                            }
    
                                                          ]
    
                                              },
    
                                'type': 'KeyError',
    
                                'module': u'exceptions',
    
                                'value': u"'name'"
    
                                }
    
                              ]
    
                    },
    
                '/oauth/callback',
    
                u'nuaaysdeMacBook-Pro.local',
    
                {'sys.argv': ("'.venv/bin/gunicorn'", "'--name=gcloud'", "'--preload'", "'--workers=4'", "'--worker-class=tornado'", "'--bind=0.0.0.0:5000'", "'--log-level=DEBUG'", "'--access-logfile=access.log'", "'--error-logfile=error.log'", "'titans:app'")
    
                },
    
                'd8516b6a7cff4261a904a816504dd0eb',
    
                {'python': '2.7.10'},
    
                {},
    
                40,
    
                {'url': u'http://127.0.0.1:5000/oauth/callback',
    
                  'headers': {'Accept-Language': 'en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7', 'Accept-Encoding': 'gzip, deflate, br', 'Host': '127.0.0.1:5000', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36', 'Connection': 'keep-alive', 'Cookie': 'session=eyJPQVVUSF9BRlRFUl9MT0dJTl9TRVNTSU9OX1VSTCI6Ii8ifQ.DTDDRg.oW8B4bGCRz1RWWo36GwLKctcHlw', 'Cache-Control': 'max-age=0', 'Upgrade-Insecure-Requests': '1'},
    
                  'env': {'SERVER_NAME': '127.0.0.1', 'SERVER_PORT': '5000', 'REMOTE_ADDR': '127.0.0.1'},
    
                  'query_string': u'code=2109d42687cc00d85129d795d5ad8ad905be5bc19533215be817f6b8c5783f31', 'data': {}, 'method': 'GET'
    
                },
    
                '2',
    
                'python',
    
                {'ip_address': '127.0.0.1'},
    
                datetime.datetime(2018, 1, 5, 8, 5, 29, 750664),
    
                u"KeyError: 'name'",
    
                {},
    
                {'version': '6.4.0', 'name': 'raven-python'}
    
            ]
    
    

    相关文章

      网友评论

          本文标题:raven.contrib.flask.Sentry的base.

          本文链接:https://www.haomeiwen.com/subject/jpwenxtx.html