示例#1
0
    def test_flush_empty(self):
        spans_names_list = []

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

        self.assertTrue(span_processor.force_flush())
示例#2
0
    def test_flush_from_multiple_threads(self):
        num_threads = 50
        num_spans = 10

        span_list = []

        my_exporter = MySpanExporter(destination=span_list)
        span_processor = export.BatchSpanProcessor(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))
示例#3
0
    def test_batch_span_processor_environment_variables(self):

        batch_span_processor = export.BatchSpanProcessor(
            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)
示例#4
0
    def test_flush_timeout(self):
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list,
                                     export_timeout_millis=500)
        span_processor = export.BatchSpanProcessor(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()
示例#5
0
    def test_on_start_accepts_parent_context(self):
        # pylint: disable=no-self-use
        my_exporter = MySpanExporter(destination=[])
        span_processor = mock.Mock(
            wraps=export.BatchSpanProcessor(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)
示例#6
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.BatchSpanProcessor(my_exporter,
                                                   max_queue_size=512,
                                                   max_export_batch_size=128)

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

        time.sleep(1)
        self.assertTrue(span_processor.force_flush())
        self.assertEqual(len(spans_names_list), 512)
        span_processor.shutdown()
示例#7
0
    def test_shutdown(self):
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.BatchSpanProcessor(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_fork(self):
        # pylint: disable=invalid-name
        tracer_provider = trace.TracerProvider()
        tracer = tracer_provider.get_tracer(__name__)

        exporter = InMemorySpanExporter()
        span_processor = export.BatchSpanProcessor(
            exporter,
            max_queue_size=256,
            max_export_batch_size=64,
            schedule_delay_millis=10,
        )
        tracer_provider.add_span_processor(span_processor)
        with tracer.start_as_current_span("foo"):
            pass
        time.sleep(0.5)  # give some time for the exporter to upload spans

        self.assertTrue(span_processor.force_flush())
        self.assertEqual(len(exporter.get_finished_spans()), 1)
        exporter.clear()

        def child(conn):
            def _target():
                with tracer.start_as_current_span("span") as s:
                    s.set_attribute("i", "1")
                    with tracer.start_as_current_span("temp"):
                        pass

            self.run_with_many_threads(_target, 100)

            time.sleep(0.5)

            spans = exporter.get_finished_spans()
            conn.send(len(spans) == 200)
            conn.close()

        parent_conn, child_conn = multiprocessing.Pipe()
        p = multiprocessing.Process(target=child, args=(child_conn, ))
        p.start()
        self.assertTrue(parent_conn.recv())
        p.join()

        span_processor.shutdown()
示例#9
0
    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.BatchSpanProcessor(
            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()
示例#10
0
    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.BatchSpanProcessor(
            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()
示例#11
0
    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.BatchSpanProcessor(
            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()
示例#12
0
    def test_flush(self):
        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.BatchSpanProcessor(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()
示例#13
0
    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.BatchSpanProcessor(
            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()