Пример #1
0
    def prepare_composite_report_json(self, reports):
        invocation_report = None
        for report in reports:
            if report["type"] == "Invocation":
                invocation_report = report

        if not invocation_report:
            return []

        common_fields = composite.init_composite_data_common_fields(
            invocation_report["data"])

        batches = self.get_report_batches(reports)
        batched_reports = []

        for batch in batches:
            all_monitoring_data = [
                composite.remove_common_fields(report["data"])
                for report in batch
            ]
            composite_data = composite.get_composite_data(
                all_monitoring_data, self.api_key, common_fields)
            try:
                batched_reports.append(
                    to_json(composite_data, separators=(',', ':')))

            except TypeError:
                logger.error(
                    "Couldn't dump report with type Composite to json string, "
                    "probably it contains a byte array")

        return batched_reports
Пример #2
0
def test_create_span_listener_with_multiple_filter_and_listener(
        span_listener_with_multiple_filterers_and_listeners):
    sl_env_var = to_json(span_listener_with_multiple_filterers_and_listeners)
    ConfigProvider.set(config_names.THUNDRA_TRACE_SPAN_LISTENERCONFIG,
                       sl_env_var)

    trace_support._parse_span_listeners()

    sl = trace_support.get_span_listeners()[0]
    f1 = sl.filterer.span_filters[0]
    f2 = sl.filterer.span_filters[1]

    assert type(sl) is FilteringSpanListener
    assert type(sl.listener) is LatencyInjectorSpanListener
    assert sl.listener.delay == 370
    assert sl.listener.distribution == 'normal'
    assert sl.listener.sigma == 73
    assert sl.listener.variation == 37

    assert f1.class_name == 'AWS-SQS'
    assert f1.domain_name == 'Messaging'
    assert f1.tags == {'foo': 'bar'}

    assert f2.class_name == 'HTTP'
    assert f2.operation_name == 'http_request'
    assert f2.tags == {'http.host': 'foobar.com'}
Пример #3
0
    def send_reports(self, reports, **opts):
        if not self.api_key:
            debug_logger("API key not set, not sending report to Thundra.")
            return []

        headers = {
            'Content-Type': 'application/json',
            'Authorization': 'ApiKey ' + self.api_key
        }
        test_run_event = opts.get("test_run_event", False)
        rest_composite_data_enabled = ConfigProvider.get(
            config_names.THUNDRA_REPORT_REST_COMPOSITE_ENABLE, True)
        if not test_run_event:
            path = constants.COMPOSITE_DATA_PATH if rest_composite_data_enabled else constants.PATH
        else:
            path = constants.PATH
        base_url = self.get_collector_url()
        request_url = base_url + path

        if ConfigProvider.get(config_names.THUNDRA_REPORT_CLOUDWATCH_ENABLE):
            if ConfigProvider.get(
                    config_names.THUNDRA_REPORT_CLOUDWATCH_COMPOSITE_ENABLE,
                    True):
                if not test_run_event:
                    reports_json = self.prepare_composite_report_json(reports)
                else:
                    reports_json = self.prepare_report_json(reports)
                for report in reports_json:
                    print(report)
            else:
                for report in reports:
                    try:
                        print(to_json(report, separators=(',', ':')))
                    except TypeError:
                        logger.error((
                            "Couldn't dump report with type {} to json string, "
                            "probably it contains a byte array").format(
                                report.get('type')))

            return []
        if not test_run_event and rest_composite_data_enabled:
            reports_json = self.prepare_composite_report_json(reports)
        else:
            reports_json = self.prepare_report_json(reports)
        responses = []
        if len(reports_json) > 0:
            _futures = [
                self.pool.submit(self.send_batch, (request_url, headers, data))
                for data in reports_json
            ]
            responses = [
                future.result() for future in futures.as_completed(_futures)
            ]

        if ConfigProvider.get(config_names.THUNDRA_DEBUG_ENABLE):
            debug_logger("Thundra API responses: " + str(responses))
        return responses
Пример #4
0
 def after_invocation(self, execution_context):
     executor = self.plugin_context.executor
     if executor:
         executor.finish_invocation(execution_context)
     report_data = {
         'apiKey': self.plugin_context.api_key,
         'type': 'Invocation',
         'dataModelVersion': constants.DATA_FORMAT_VERSION,
         'data': execution_context.invocation_data
     }
     execution_context.report(json.loads(to_json(report_data)))
Пример #5
0
def test_create_empty_span_listener(empty_span_listener):
    sl_env_var = to_json(empty_span_listener)
    ConfigProvider.set(config_names.THUNDRA_TRACE_SPAN_LISTENERCONFIG,
                       sl_env_var)

    trace_support._parse_span_listeners()

    sl = trace_support.get_span_listeners()[0]

    assert type(sl) is FilteringSpanListener
    assert type(sl.listener) is ErrorInjectorSpanListener
    assert type(sl.filterer) is StandardSpanFilterer
Пример #6
0
def test_create_span_listener_with_only_listener(
        span_listener_with_one_listener):
    sl_env_var = to_json(span_listener_with_one_listener)
    ConfigProvider.set(config_names.THUNDRA_TRACE_SPAN_LISTENERCONFIG,
                       sl_env_var)

    trace_support._parse_span_listeners()

    sl = trace_support.get_span_listeners()[0]

    assert type(sl) is FilteringSpanListener
    assert type(sl.listener) is ErrorInjectorSpanListener
    assert sl.listener.error_type is NameError
    assert sl.listener.error_message == 'foo'
    assert type(sl.filterer) is StandardSpanFilterer
Пример #7
0
 def prepare_report_json(self, reports):
     batches = self.get_report_batches(reports)
     batched_reports = []
     for batch in batches:
         report_jsons = []
         for report in batch:
             try:
                 report_jsons.append(to_json(report, separators=(',', ':')))
             except TypeError:
                 logger.error(
                     ("Couldn't dump report with type {} to json string, "
                      "probably it contains a byte array").format(
                          report.get('type')))
         json_string = "[{}]".format(','.join(report_jsons))
         batched_reports.append(json_string)
     return batched_reports
Пример #8
0
def test_create_span_listener_with_only_filterer(
        span_listener_with_one_filterer):
    sl_env_var = to_json(span_listener_with_one_filterer)
    ConfigProvider.set(config_names.THUNDRA_TRACE_SPAN_LISTENERCONFIG,
                       sl_env_var)

    trace_support._parse_span_listeners()

    sl = trace_support.get_span_listeners()[0]
    f = sl.filterer.span_filters[0]

    assert type(sl) is FilteringSpanListener
    assert sl.listener is None
    assert f.class_name == 'AWS-SQS'
    assert f.domain_name == 'Messaging'
    assert f.tags == {'foo': 'bar'}
Пример #9
0
def test_send_report_to_url(mock_requests, mock_report):
    ConfigProvider.set(config_names.THUNDRA_REPORT_REST_BASEURL, 'different_url/api')
    ConfigProvider.set(config_names.THUNDRA_REPORT_REST_COMPOSITE_ENABLE, 'false')
    test_session = mock_requests.Session()
    reporter = Reporter('api key', session=test_session)
    responses = reporter.send_reports([mock_report])

    post_url = 'different_url/api/monitoring-data'
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'ApiKey api key'
    }

    reporter.session.post.assert_called_once_with(post_url, data=to_json([mock_report], separators=(',', ':')),
                                                  headers=headers, timeout=constants.DEFAULT_REPORT_TIMEOUT)
    reporter.session.post.return_value.status_code = 200
    for response in responses:
        assert response.status_code == 200
Пример #10
0
    def before_call(self, scope, wrapped, instance, args, kwargs, response,
                    exception):
        scope.span.domain_name = constants.DomainNames['AWS']
        scope.span.class_name = constants.ClassNames['STEPFUNCTIONS']

        _, request_data = args
        state_machine_arn = request_data.get('stateMachineArn', '')
        execution_name = request_data.get('name', '')

        service_name = instance.__class__.__name__.lower()

        try:
            orig_input = request_data.get('input', None)
            if orig_input != None and ConfigProvider.get(
                    config_names.THUNDRA_LAMBDA_AWS_STEPFUNCTIONS):
                parsed_input = json.loads(orig_input)
                trace_link = str(uuid.uuid4())
                parsed_input['_thundra'] = {
                    "trace_link": trace_link,
                    "step": 0
                }
                scope.span.set_tag(
                    constants.AwsStepFunctionsTags['EXECUTION_INPUT'],
                    orig_input)
                request_data['input'] = to_json(parsed_input)
                scope.span.set_tag(constants.SpanTags['TRACE_LINKS'],
                                   [trace_link])
                scope.span.resource_trace_links = [trace_link]
        except:
            pass

        if len(args) > 0:
            scope.span.set_tag(constants.AwsSDKTags['REQUEST_NAME'], args[0])
            scope.span.set_tag(
                constants.SpanTags['OPERATION_TYPE'],
                get_operation_type(scope.span.class_name, args[0]))

        scope.span.set_tag(constants.AwsSDKTags['SERVICE_NAME'], service_name)
        scope.span.set_tag(constants.AwsStepFunctionsTags['STATE_MACHINE_ARN'],
                           state_machine_arn)
        scope.span.set_tag(constants.AwsStepFunctionsTags['EXECUTION_NAME'],
                           execution_name)

        scope.span.set_tag(constants.SpanTags['TOPOLOGY_VERTEX'], True)
Пример #11
0
def test_create_span_listener_with_filterer_and_listener(
        span_listener_with_filterer_and_listener):
    sl_env_var = to_json(span_listener_with_filterer_and_listener)
    ConfigProvider.set(config_names.THUNDRA_TRACE_SPAN_LISTENERCONFIG,
                       sl_env_var)

    trace_support._parse_span_listeners()

    sl = trace_support.get_span_listeners()[0]
    f = sl.filterer.span_filters[0]

    assert type(sl) is FilteringSpanListener
    assert type(sl.listener) is ErrorInjectorSpanListener
    assert sl.listener.error_type is NameError
    assert sl.listener.error_message == 'foo'
    assert sl.listener.inject_on_finish
    assert sl.listener.inject_count_freq

    assert f.class_name == 'AWS-SQS'
    assert f.domain_name == 'Messaging'
    assert f.tags == {'foo': 'bar'}