예제 #1
0
def _report_exc_info(exc_info, request, extra_data, payload_data, level=None):
    """
    Called by report_exc_info() wrapper
    """
    # check if exception is marked ignored
    cls, exc, trace = exc_info
    if getattr(exc, '_rollbar_ignore', False) or _is_ignored(exc):
        return

    if not _check_config():
        return

    data = _build_base_data(request)

    filtered_level = _filtered_level(exc)
    if filtered_level:
        data['level'] = filtered_level

    # explicitly override the level with provided level
    if level:
        data['level'] = level

    # walk the trace chain to collect cause and context exceptions
    trace_chain = _walk_trace_chain(cls, exc, trace)

    extra_trace_data = None
    if len(trace_chain) > 1:
        data['body'] = {
            'trace_chain': trace_chain
        }
        if payload_data and payload_data['body'] and payload_data['body']['trace']:
            extra_trace_data = payload_data['body']['trace']
            del payload_data['body']['trace']
    else:
        data['body'] = {
            'trace': trace_chain[0]
        }

    if extra_data:
        extra_data = extra_data
        if not isinstance(extra_data, dict):
            extra_data = {'value': extra_data}
        if extra_trace_data:
            extra_data = dict_merge(extra_data, extra_trace_data)
        data['custom'] = extra_data
    if extra_trace_data and not extra_data:
        data['custom'] = extra_trace_data

    _add_request_data(data, request)
    _add_person_data(data, request)
    _add_lambda_context_data(data)
    data['server'] = _build_server_data()

    if payload_data:
        data = dict_merge(data, payload_data)

    payload = _build_payload(data)
    send_payload(payload, data.get('access_token'))

    return data['uuid']
예제 #2
0
def _report_message(message, level, request, extra_data, payload_data):
    """
    Called by report_message() wrapper
    """
    if not _check_config():
        return

    data = _build_base_data(request, level=level)

    # message
    data['body'] = {'message': {'body': message}}

    if extra_data:
        extra_data = extra_data
        data['body']['message'].update(extra_data)

    _add_request_data(data, request)
    _add_person_data(data, request)
    data['server'] = _build_server_data()

    if payload_data:
        data = dict_merge(data, payload_data)

    payload = _build_payload(data)
    send_payload(payload, data.get('access_token'))

    return data['uuid']
예제 #3
0
def _report_message(message, level, request, extra_data, payload_data):
    """
    Called by report_message() wrapper
    """
    if not _check_config():
        return

    data = _build_base_data(request, level=level)

    # message
    data['body'] = {
        'message': {
            'body': message
        }
    }

    if extra_data:
        extra_data = extra_data
        data['body']['message'].update(extra_data)

    _add_request_data(data, request)
    _add_person_data(data, request)
    data['server'] = _build_server_data()

    if payload_data:
        data = dict_merge(data, payload_data)

    payload = _build_payload(data)
    send_payload(payload, data.get('access_token'))

    return data['uuid']
예제 #4
0
def _add_lambda_context_data(data):
    """
    Attempts to add information from the lambda context if it exists
    """
    global _CURRENT_LAMBDA_CONTEXT
    context = _CURRENT_LAMBDA_CONTEXT
    if context is None:
        return
    try:
        lambda_data = {
            'lambda': {
                'remaining_time_in_millis': context.get_remaining_time_in_millis(),
                'function_name': context.function_name,
                'function_version': context.function_version,
                'arn': context.invoked_function_arn,
                'request_id': context.aws_request_id,
            }
        }
        if 'custom' in data:
            data['custom'] = dict_merge(data['custom'], lambda_data)
        else:
            data['custom'] = lambda_data
    except Exception as e:
        log.exception("Exception while adding lambda context data: %r", e)
    finally:
        _CURRENT_LAMBDA_CONTEXT = None
예제 #5
0
def _add_lambda_context_data(data):
    """
    Attempts to add information from the lambda context if it exists
    """
    global _CURRENT_LAMBDA_CONTEXT
    context = _CURRENT_LAMBDA_CONTEXT
    if context is None:
        return
    try:
        lambda_data = {
            'lambda': {
                'remaining_time_in_millis': context.get_remaining_time_in_millis(),
                'function_name': context.function_name,
                'function_version': context.function_version,
                'arn': context.invoked_function_arn,
                'request_id': context.aws_request_id,
            }
        }
        if 'custom' in data:
            data['custom'] = dict_merge(data['custom'], lambda_data)
        else:
            data['custom'] = lambda_data
    except Exception as e:
        log.exception("Exception while adding lambda context data: %r", e)
    finally:
        _CURRENT_LAMBDA_CONTEXT = None
예제 #6
0
    def test_dict_merge_dicts_second_wins(self):
        a = {'a': {'b': 42}}
        b = {'a': {'b': 99}}
        result = dict_merge(a, b)

        self.assertIn('a', result)
        self.assertIn('b', result['a'])
        self.assertEqual(99, result['a']['b'])
예제 #7
0
    def test_dict_merge_dicts_second_wins(self):
        a = {'a': {'b': 42}}
        b = {'a': {'b': 99}}
        result = dict_merge(a, b)

        self.assertIn('a', result)
        self.assertIn('b', result['a'])
        self.assertEqual(99, result['a']['b'])
예제 #8
0
def _report_exc_info(exc_info, request, extra_data, payload_data, level=None):
    """
    Called by report_exc_info() wrapper
    """
    # check if exception is marked ignored
    cls, exc, trace = exc_info
    if getattr(exc, '_rollbar_ignore', False) or _is_ignored(exc):
        return

    if not _check_config():
        return

    data = _build_base_data(request)

    filtered_level = _filtered_level(exc)
    if filtered_level:
        data['level'] = filtered_level

    # explicitly override the level with provided level
    if level:
        data['level'] = level

    # exception info
    # most recent call last
    raw_frames = traceback.extract_tb(trace)
    frames = [{'filename': f[0], 'lineno': f[1], 'method': f[2], 'code': f[3]} for f in raw_frames]

    data['body'] = {
        'trace': {
            'frames': frames,
            'exception': {
                'class': cls.__name__,
                'message': text(exc),
            }
        }
    }

    if extra_data:
        extra_data = extra_data
        if isinstance(extra_data, dict):
            data['custom'] = extra_data
        else:
            data['custom'] = {'value': extra_data}

    _add_locals_data(data, exc_info)
    _add_request_data(data, request)
    _add_person_data(data, request)
    data['server'] = _build_server_data()

    if payload_data:
        data = dict_merge(data, payload_data)

    payload = _build_payload(data)
    send_payload(payload, data.get('access_token'))

    return data['uuid']
예제 #9
0
파일: __init__.py 프로젝트: artps/pyrollbar
def _report_exc_info(exc_info, request, extra_data, payload_data, level=None):
    """
    Called by report_exc_info() wrapper
    """
    # check if exception is marked ignored
    cls, exc, trace = exc_info
    if getattr(exc, '_rollbar_ignore', False) or _is_ignored(exc):
        return

    if not _check_config():
        return

    data = _build_base_data(request)

    filtered_level = _filtered_level(exc)
    if filtered_level:
        data['level'] = filtered_level

    # explicitly override the level with provided level
    if level:
        data['level'] = level

    # exception info
    # most recent call last
    raw_frames = traceback.extract_tb(trace)
    frames = [{'filename': f[0], 'lineno': f[1], 'method': f[2], 'code': f[3]} for f in raw_frames]

    data['body'] = {
        'trace': {
            'frames': frames,
            'exception': {
                'class': cls.__name__,
                'message': text(exc),
            }
        }
    }

    if extra_data:
        extra_data = extra_data
        if isinstance(extra_data, dict):
            data['custom'] = extra_data
        else:
            data['custom'] = {'value': extra_data}

    _add_locals_data(data, exc_info)
    _add_request_data(data, request)
    _add_person_data(data, request)
    data['server'] = _build_server_data()

    if payload_data:
        data = dict_merge(data, payload_data)

    payload = _build_payload(data)
    send_payload(payload, data.get('access_token'))

    return data['uuid']
예제 #10
0
    def test_dict_merge_dicts_independent(self):
        a = {'a': {'b': 42}}
        b = {'x': {'y': 99}}
        result = dict_merge(a, b)

        self.assertIn('a', result)
        self.assertIn('b', result['a'])
        self.assertEqual(42, result['a']['b'])
        self.assertIn('x', result)
        self.assertIn('y', result['x'])
        self.assertEqual(99, result['x']['y'])
예제 #11
0
    def test_dict_merge_dicts_independent(self):
        a = {'a': {'b': 42}}
        b = {'x': {'y': 99}}
        result = dict_merge(a, b)

        self.assertIn('a', result)
        self.assertIn('b', result['a'])
        self.assertEqual(42, result['a']['b'])
        self.assertIn('x', result)
        self.assertIn('y', result['x'])
        self.assertEqual(99, result['x']['y'])
예제 #12
0
    def test_dict_merge_dicts_select_poll(self):
        import select
        poll = getattr(select, 'poll', None)
        if poll is None:
            return
        p = poll()
        a = {'a': {'b': 42}}
        b = {'a': {'y': p}}
        result = dict_merge(a, b)

        self.assertIn('a', result)
        self.assertIn('b', result['a'])
        self.assertEqual(42, result['a']['b'])
        self.assertIn('y', result['a'])
        self.assertRegex(result['a']['y'], r'Uncopyable obj')
예제 #13
0
    def test_dict_merge_dicts_select_poll(self):
        import select
        poll = getattr(select, 'poll', None)
        if poll is None:
            return
        p = poll()
        a = {'a': {'b': 42}}
        b = {'a': {'y': p}}
        result = dict_merge(a, b, silence_errors=True)

        self.assertIn('a', result)
        self.assertIn('b', result['a'])
        self.assertEqual(42, result['a']['b'])
        self.assertIn('y', result['a'])
        self.assertRegex(result['a']['y'], r'Uncopyable obj')
예제 #14
0
def _report_message(message, level, request, extra_data, payload_data):
    """
    Called by report_message() wrapper
    """
    if not _check_config():
        return

    filtered_message = events.on_message(message,
                                         request=request,
                                         extra_data=extra_data,
                                         payload_data=payload_data,
                                         level=level)

    if filtered_message is False:
        return

    data = _build_base_data(request, level=level)

    # message
    data['body'] = {
        'message': {
            'body': filtered_message
        }
    }

    if extra_data:
        extra_data = extra_data
        data['body']['message'].update(extra_data)

    request = _get_actual_request(request)
    _add_request_data(data, request)
    _add_person_data(data, request)
    _add_lambda_context_data(data)
    data['server'] = _build_server_data()

    if payload_data:
        data = dict_merge(data, payload_data)

    payload = _build_payload(data)
    send_payload(payload, data.get('access_token'))

    return data['uuid']
예제 #15
0
def _report_message(message, level, request, extra_data, payload_data):
    """
    Called by report_message() wrapper
    """
    if not _check_config():
        return

    filtered_message = events.on_message(message,
                                         request=request,
                                         extra_data=extra_data,
                                         payload_data=payload_data,
                                         level=level)

    if filtered_message is False:
        return

    data = _build_base_data(request, level=level)

    # message
    data['body'] = {
        'message': {
            'body': filtered_message
        }
    }

    if extra_data:
        extra_data = extra_data
        data['body']['message'].update(extra_data)

    request = _get_actual_request(request)
    _add_request_data(data, request)
    _add_person_data(data, request)
    _add_lambda_context_data(data)
    data['server'] = _build_server_data()

    if payload_data:
        data = dict_merge(data, payload_data)

    payload = _build_payload(data)
    send_payload(payload, payload.get('access_token'))

    return data['uuid']
예제 #16
0
    def __init__(self, access_token, environment=None, **kw):
        """
        Creates a standalone Rollbar instance.
        Allows for more flexibility in multiple tools reporting to rollbar
        in the same runtime.

        access_token: project access token. Get this from the Rollbar UI:
                      - click "Settings" in the top nav
                      - click "Projects" in the left nav
                      - copy-paste the appropriate token.
        environment: environment name. Can be any string; suggestions: 'production', 'development',
                     'staging', 'yourname'
        **kw: provided keyword arguments will override keys in SETTINGS.
        """
        # We will perform these transforms in order:
        # 1. Serialize the payload to be all python built-in objects
        # 2. Scrub the payloads based on the key suffixes in SETTINGS['scrub_fields']
        # 3. Scrub URLs in the payload for keys that end with 'url'
        # 4. Optional - If local variable gathering is enabled, transform the
        #       trace frame values using the ShortReprTransform.
        self._serialize_transform = SerializableTransform(safe_repr=self.settings['locals']['safe_repr'],
                                                          whitelist_types=self.settings['locals']['whitelisted_types'])

        self.settings = copy.deepcopy(self.settings)
        self._update_transforms()

        self.settings['access_token'] = access_token
        if not environment:
            # Allow settings via environment variable
            environment = os.environ.get('ROLLBAR_ENV', 'production')
            self.settings['environment'] = environment

        # Merge the extra config settings into self.settings
        self.settings = dict_merge(self.settings, kw)

        # TODO - (bchapman)
        if self.settings.get('allow_logging_basic_config'):
            logging.basicConfig()

        if self.settings.get('handler') == 'agent':
            self.agent_log = self._create_agent_log()
예제 #17
0
def _report_exc_info(exc_info, request, extra_data, payload_data, level=None):
    """
    Called by report_exc_info() wrapper
    """

    if not _check_config():
        return

    filtered_level = _filtered_level(exc_info[1])
    if level is None:
        level = filtered_level

    filtered_exc_info = events.on_exception_info(exc_info,
                                                 request=request,
                                                 extra_data=extra_data,
                                                 payload_data=payload_data,
                                                 level=level)

    if filtered_exc_info is False:
        return

    cls, exc, trace = filtered_exc_info

    data = _build_base_data(request)
    if level is not None:
        data['level'] = level

    # walk the trace chain to collect cause and context exceptions
    trace_chain = _walk_trace_chain(cls, exc, trace)

    extra_trace_data = None
    if len(trace_chain) > 1:
        data['body'] = {
            'trace_chain': trace_chain
        }
        if payload_data and ('body' in payload_data) and ('trace' in payload_data['body']):
            extra_trace_data = payload_data['body']['trace']
            del payload_data['body']['trace']
    else:
        data['body'] = {
            'trace': trace_chain[0]
        }

    if extra_data:
        extra_data = extra_data
        if not isinstance(extra_data, dict):
            extra_data = {'value': extra_data}
        if extra_trace_data:
            extra_data = dict_merge(extra_data, extra_trace_data)
        data['custom'] = extra_data
    if extra_trace_data and not extra_data:
        data['custom'] = extra_trace_data

    request = _get_actual_request(request)
    _add_request_data(data, request)
    _add_person_data(data, request)
    _add_lambda_context_data(data)
    data['server'] = _build_server_data()

    if payload_data:
        data = dict_merge(data, payload_data)

    payload = _build_payload(data)
    send_payload(payload, payload.get('access_token'))

    return data['uuid']
예제 #18
0
def _report_exc_info(exc_info, request, extra_data, payload_data, level=None):
    """
    Called by report_exc_info() wrapper
    """

    if not _check_config():
        return

    filtered_level = _filtered_level(exc_info[1])
    if level is None:
        level = filtered_level

    filtered_exc_info = events.on_exception_info(exc_info,
                                                 request=request,
                                                 extra_data=extra_data,
                                                 payload_data=payload_data,
                                                 level=level)

    if filtered_exc_info is False:
        return

    cls, exc, trace = filtered_exc_info

    data = _build_base_data(request)
    if level is not None:
        data['level'] = level

    # walk the trace chain to collect cause and context exceptions
    trace_chain = _walk_trace_chain(cls, exc, trace)

    extra_trace_data = None
    if len(trace_chain) > 1:
        data['body'] = {
            'trace_chain': trace_chain
        }
        if payload_data and ('body' in payload_data) and ('trace' in payload_data['body']):
            extra_trace_data = payload_data['body']['trace']
            del payload_data['body']['trace']
    else:
        data['body'] = {
            'trace': trace_chain[0]
        }

    if extra_data:
        extra_data = extra_data
        if not isinstance(extra_data, dict):
            extra_data = {'value': extra_data}
        if extra_trace_data:
            extra_data = dict_merge(extra_data, extra_trace_data)
        data['custom'] = extra_data
    if extra_trace_data and not extra_data:
        data['custom'] = extra_trace_data

    _add_request_data(data, request)
    _add_person_data(data, request)
    _add_lambda_context_data(data)
    data['server'] = _build_server_data()

    if payload_data:
        data = dict_merge(data, payload_data)

    payload = _build_payload(data)
    send_payload(payload, data.get('access_token'))

    return data['uuid']
예제 #19
0
def init(access_token, environment='production', **kw):
    """
    Saves configuration variables in this module's SETTINGS.

    access_token: project access token. Get this from the Rollbar UI:
                  - click "Settings" in the top nav
                  - click "Projects" in the left nav
                  - copy-paste the appropriate token.
    environment: environment name. Can be any string; suggestions: 'production', 'development',
                 'staging', 'yourname'
    **kw: provided keyword arguments will override keys in SETTINGS.
    """
    global SETTINGS, agent_log, _initialized, _transforms, _serialize_transform, _threads

    # Merge the extra config settings into SETTINGS
    SETTINGS = dict_merge(SETTINGS, kw)
    if _initialized:
        # NOTE: Temp solution to not being able to re-init.
        # New versions of pyrollbar will support re-initialization
        # via the (not-yet-implemented) configure() method.
        if not SETTINGS.get('suppress_reinit_warning'):
            log.warning('Rollbar already initialized. Ignoring re-init.')
        return

    SETTINGS['access_token'] = access_token
    SETTINGS['environment'] = environment

    if SETTINGS.get('allow_logging_basic_config'):
        logging.basicConfig()

    if SETTINGS.get('handler') == 'agent':
        agent_log = _create_agent_log()

    # We will perform these transforms in order:
    # 1. Serialize the payload to be all python built-in objects
    # 2. Scrub the payloads based on the key suffixes in SETTINGS['scrub_fields']
    # 3. Scrub URLs in the payload for keys that end with 'url'
    # 4. Optional - If local variable gathering is enabled, transform the
    #       trace frame values using the ShortReprTransform.
    _serialize_transform = SerializableTransform(safe_repr=SETTINGS['locals']['safe_repr'],
                                                 whitelist_types=SETTINGS['locals']['whitelisted_types'])
    _transforms = [
        ScrubRedactTransform(),
        _serialize_transform,
        ScrubTransform(suffixes=[(field,) for field in SETTINGS['scrub_fields']], redact_char='*'),
        ScrubUrlTransform(suffixes=[(field,) for field in SETTINGS['url_fields']], params_to_scrub=SETTINGS['scrub_fields'])
    ]

    # A list of key prefixes to apply our shortener transform to. The request
    # being included in the body key is old behavior and is being retained for
    # backwards compatibility.
    shortener_keys = [
        ('request', 'POST'),
        ('request', 'json'),
        ('body', 'request', 'POST'),
        ('body', 'request', 'json'),
    ]

    if SETTINGS['locals']['enabled']:
        shortener_keys.append(('body', 'trace', 'frames', '*', 'code'))
        shortener_keys.append(('body', 'trace', 'frames', '*', 'args', '*'))
        shortener_keys.append(('body', 'trace', 'frames', '*', 'kwargs', '*'))
        shortener_keys.append(('body', 'trace', 'frames', '*', 'locals', '*'))

    shortener_keys.extend(SETTINGS['shortener_keys'])

    shortener = ShortenerTransform(safe_repr=SETTINGS['locals']['safe_repr'],
                                   keys=shortener_keys,
                                   **SETTINGS['locals']['sizes'])
    _transforms.append(shortener)
    _threads = queue.Queue()
    events.reset()
    filters.add_builtin_filters(SETTINGS)

    _initialized = True
예제 #20
0
    def test_dict_merge_not_dict(self):
        a = {'a': {'b': 42}}
        b = 99
        result = dict_merge(a, b)

        self.assertEqual(99, result)
예제 #21
0
def init(access_token, environment='production', **kw):
    """
    Saves configuration variables in this module's SETTINGS.

    access_token: project access token. Get this from the Rollbar UI:
                  - click "Settings" in the top nav
                  - click "Projects" in the left nav
                  - copy-paste the appropriate token.
    environment: environment name. Can be any string; suggestions: 'production', 'development',
                 'staging', 'yourname'
    **kw: provided keyword arguments will override keys in SETTINGS.
    """
    global SETTINGS, agent_log, _initialized, _transforms, _serialize_transform

    if _initialized:
        # NOTE: Temp solution to not being able to re-init.
        # New versions of pyrollbar will support re-initialization
        # via the (not-yet-implemented) configure() method.
        log.warn('Rollbar already initialized. Ignoring re-init.')
        return

    SETTINGS['access_token'] = access_token
    SETTINGS['environment'] = environment

    # Merge the extra config settings into SETTINGS
    SETTINGS = dict_merge(SETTINGS, kw)

    if SETTINGS.get('allow_logging_basic_config'):
        logging.basicConfig()

    if SETTINGS.get('handler') == 'agent':
        agent_log = _create_agent_log()

    # We will perform these transforms in order:
    # 1. Serialize the payload to be all python built-in objects
    # 2. Scrub the payloads based on the key suffixes in SETTINGS['scrub_fields']
    # 3. Scrub URLs in the payload for keys that end with 'url'
    # 4. Optional - If local variable gathering is enabled, transform the
    #       trace frame values using the ShortReprTransform.
    _serialize_transform = SerializableTransform(safe_repr=SETTINGS['locals']['safe_repr'],
                                                 whitelist_types=SETTINGS['locals']['whitelisted_types'])
    _transforms = [
        ScrubRedactTransform(),
        _serialize_transform,
        ScrubTransform(suffixes=[(field,) for field in SETTINGS['scrub_fields']], redact_char='*'),
        ScrubUrlTransform(suffixes=[(field,) for field in SETTINGS['url_fields']], params_to_scrub=SETTINGS['scrub_fields'])
    ]

    # A list of key prefixes to apply our shortener transform to
    shortener_keys = [
        ('body', 'request', 'POST'),
        ('body', 'request', 'json'),
    ]

    if SETTINGS['locals']['enabled']:
        shortener_keys.append(('body', 'trace', 'frames', '*', 'code'))
        shortener_keys.append(('body', 'trace', 'frames', '*', 'args', '*'))
        shortener_keys.append(('body', 'trace', 'frames', '*', 'kwargs', '*'))
        shortener_keys.append(('body', 'trace', 'frames', '*', 'locals', '*'))

    shortener = ShortenerTransform(safe_repr=SETTINGS['locals']['safe_repr'],
                                   keys=shortener_keys,
                                   **SETTINGS['locals']['sizes'])
    _transforms.append(shortener)

    _initialized = True
예제 #22
0
    def test_dict_merge_not_dict(self):
        a = {'a': {'b': 42}}
        b = 99
        result = dict_merge(a, b)

        self.assertEqual(99, result)