def test_flush_from_multiple_threads(self):
        num_threads = 50
        num_spans = 10

        span_list = []

        my_exporter = MySpanExporter(destination=span_list)
        span_processor = export.BatchExportSpanProcessor(
            my_exporter, max_queue_size=512, max_export_batch_size=128
        )

        def create_spans_and_flush(tno: int):
            for span_idx in range(num_spans):
                _create_start_and_end_span(
                    "Span {}-{}".format(tno, span_idx), span_processor
                )
            self.assertTrue(span_processor.force_flush())

        with ThreadPoolExecutor(max_workers=num_threads) as executor:
            future_list = []
            for thread_no in range(num_threads):
                future = executor.submit(create_spans_and_flush, thread_no)
                future_list.append(future)

            executor.shutdown()

        self.assertEqual(num_threads * num_spans, len(span_list))
    def test_flush_empty(self):
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.BatchExportSpanProcessor(my_exporter)

        self.assertTrue(span_processor.force_flush())
    def test_batch_span_processor_environment_variables(self):

        batch_span_processor = export.BatchExportSpanProcessor(
            MySpanExporter(destination=[]))

        self.assertEqual(batch_span_processor.max_queue_size, 10)
        self.assertEqual(batch_span_processor.schedule_delay_millis, 2)
        self.assertEqual(batch_span_processor.max_export_batch_size, 3)
        self.assertEqual(batch_span_processor.export_timeout_millis, 4)
    def test_flush_timeout(self):
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list,
                                     export_timeout_millis=500)
        span_processor = export.BatchExportSpanProcessor(my_exporter)

        _create_start_and_end_span("foo", span_processor)

        # check that the timeout is not meet
        with self.assertLogs(level=WARNING):
            self.assertFalse(span_processor.force_flush(100))
        span_processor.shutdown()
    def test_batch_span_processor(self):
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.BatchExportSpanProcessor(my_exporter)

        span_names = ["xxx", "bar", "foo"]

        for name in span_names:
            _create_start_and_end_span(name, span_processor)

        span_processor.shutdown()
        self.assertListEqual(span_names, spans_names_list)
    def test_on_start_accepts_parent_context(self):
        # pylint: disable=no-self-use
        my_exporter = MySpanExporter(destination=[])
        span_processor = mock.Mock(
            wraps=export.BatchExportSpanProcessor(my_exporter))
        tracer_provider = trace.TracerProvider()
        tracer_provider.add_span_processor(span_processor)
        tracer = tracer_provider.get_tracer(__name__)

        context = Context()
        span = tracer.start_span("foo", context=context)

        span_processor.on_start.assert_called_once_with(span,
                                                        parent_context=context)
Exemple #7
0
    def test_batch_span_processor_lossless(self):
        """Test that no spans are lost when sending max_queue_size spans"""
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list,
                                     max_export_batch_size=128)
        span_processor = export.BatchExportSpanProcessor(
            my_exporter, max_queue_size=512, max_export_batch_size=128)

        for _ in range(512):
            _create_start_and_end_span("foo", span_processor)

        self.assertTrue(span_processor.force_flush())
        self.assertEqual(len(spans_names_list), 512)
        span_processor.shutdown()
Exemple #8
0
    def test_batch_span_processor_scheduled_delay(self):
        """Test that spans are exported each schedule_delay_millis"""
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.BatchExportSpanProcessor(
            my_exporter, schedule_delay_millis=50)

        # create single span
        _create_start_and_end_span("foo", span_processor)

        time.sleep(0.05 + 0.02)
        # span should be already exported
        self.assertEqual(len(spans_names_list), 1)

        span_processor.shutdown()
    def test_shutdown(self):
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.BatchExportSpanProcessor(my_exporter)

        span_names = ["xxx", "bar", "foo"]

        for name in span_names:
            _create_start_and_end_span(name, span_processor)

        span_processor.shutdown()
        self.assertTrue(my_exporter.is_shutdown)

        # check that spans are exported without an explicitly call to
        # force_flush()
        self.assertListEqual(span_names, spans_names_list)
    def test_batch_span_processor_scheduled_delay(self):
        """Test that spans are exported each schedule_delay_millis"""
        spans_names_list = []

        export_event = threading.Event()
        my_exporter = MySpanExporter(
            destination=spans_names_list, export_event=export_event
        )
        span_processor = export.BatchExportSpanProcessor(
            my_exporter, schedule_delay_millis=50,
        )

        # create single span
        start_time = time.time()
        _create_start_and_end_span("foo", span_processor)

        self.assertTrue(export_event.wait(2))
        export_time = time.time()
        self.assertEqual(len(spans_names_list), 1)
        self.assertGreaterEqual((export_time - start_time) * 1e3, 50)

        span_processor.shutdown()
    def test_batch_span_processor_not_sampled(self):
        tracer_provider = trace.TracerProvider(
            sampler=trace.sampling.ALWAYS_OFF)
        tracer = tracer_provider.get_tracer(__name__)
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list,
                                     max_export_batch_size=128)
        span_processor = export.BatchExportSpanProcessor(
            my_exporter,
            max_queue_size=256,
            max_export_batch_size=64,
            schedule_delay_millis=100,
        )
        tracer_provider.add_span_processor(span_processor)
        with tracer.start_as_current_span("foo"):
            pass
        time.sleep(0.05)  # give some time for the exporter to upload spans

        self.assertTrue(span_processor.force_flush())
        self.assertEqual(len(spans_names_list), 0)
        span_processor.shutdown()
    def test_batch_span_processor_many_spans(self):
        """Test that no spans are lost when sending many spans"""
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list,
                                     max_export_batch_size=128)
        span_processor = export.BatchExportSpanProcessor(
            my_exporter,
            max_queue_size=256,
            max_export_batch_size=64,
            schedule_delay_millis=100,
        )

        for _ in range(4):
            for _ in range(256):
                _create_start_and_end_span("foo", span_processor)

            time.sleep(0.1)  # give some time for the exporter to upload spans

        self.assertTrue(span_processor.force_flush())
        self.assertEqual(len(spans_names_list), 1024)
        span_processor.shutdown()
    def test_flush(self):
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.BatchExportSpanProcessor(my_exporter)

        span_names0 = ["xxx", "bar", "foo"]
        span_names1 = ["yyy", "baz", "fox"]

        for name in span_names0:
            _create_start_and_end_span(name, span_processor)

        self.assertTrue(span_processor.force_flush())
        self.assertListEqual(span_names0, spans_names_list)

        # create some more spans to check that span processor still works
        for name in span_names1:
            _create_start_and_end_span(name, span_processor)

        self.assertTrue(span_processor.force_flush())
        self.assertListEqual(span_names0 + span_names1, spans_names_list)

        span_processor.shutdown()
    def test_batch_span_processor_reset_timeout(self):
        """Test that the scheduled timeout is reset on cycles without spans"""
        spans_names_list = []

        export_event = threading.Event()
        my_exporter = MySpanExporter(
            destination=spans_names_list,
            export_event=export_event,
            export_timeout_millis=50,
        )

        span_processor = export.BatchExportSpanProcessor(
            my_exporter, schedule_delay_millis=50,
        )

        with mock.patch.object(span_processor.condition, "wait") as mock_wait:
            _create_start_and_end_span("foo", span_processor)
            self.assertTrue(export_event.wait(2))

            # give some time for exporter to loop
            # since wait is mocked it should return immediately
            time.sleep(0.05)
            mock_wait_calls = list(mock_wait.mock_calls)

            # find the index of the call that processed the singular span
            for idx, wait_call in enumerate(mock_wait_calls):
                _, args, __ = wait_call
                if args[0] <= 0:
                    after_calls = mock_wait_calls[idx + 1 :]
                    break

            self.assertTrue(
                all(args[0] >= 0.05 for _, args, __ in after_calls)
            )

        span_processor.shutdown()