def setUp(self):
     self.tracer_source = trace.TracerSource()
     self.tracer = self.tracer_source.get_tracer(__name__)
     self.memory_exporter = InMemorySpanExporter()
     span_processor = export.SimpleExportSpanProcessor(self.memory_exporter)
     self.tracer_source.add_span_processor(span_processor)
     self.exec_scenario()
Esempio n. 2
0
    def test_sampling_attributes(self):
        decision_attributes = {
            "sampler-attr": "sample-val",
            "attr-in-both": "decision-attr",
        }
        tracer_source = trace.TracerSource(
            sampling.StaticSampler(
                sampling.Decision(sampled=True,
                                  attributes=decision_attributes)))

        self.tracer = tracer_source.get_tracer(__name__)

        with self.tracer.start_as_current_span("root2") as root:
            self.assertEqual(len(root.attributes), 2)
            self.assertEqual(root.attributes["sampler-attr"], "sample-val")
            self.assertEqual(root.attributes["attr-in-both"], "decision-attr")

        attributes = {
            "attr-key": "val",
            "attr-key2": "val2",
            "attr-in-both": "span-attr",
        }
        with self.tracer.start_as_current_span("root2",
                                               attributes=attributes) as root:
            self.assertEqual(len(root.attributes), 4)
            self.assertEqual(root.attributes["attr-key"], "val")
            self.assertEqual(root.attributes["attr-key2"], "val2")
            self.assertEqual(root.attributes["sampler-attr"], "sample-val")
            self.assertEqual(root.attributes["attr-in-both"], "decision-attr")
Esempio n. 3
0
    def test_error_status(self):
        try:
            with trace.TracerSource().get_tracer(__name__).start_span(
                    "root") as root:
                raise Exception("unknown")
        except Exception:  # pylint: disable=broad-except
            pass

        self.assertIs(root.status.canonical_code, StatusCanonicalCode.UNKNOWN)
        self.assertEqual(root.status.description, "Exception: unknown")
Esempio n. 4
0
    def test_sampler_no_sampling(self):
        tracer_source = trace.TracerSource(sampling.ALWAYS_OFF)
        tracer = tracer_source.get_tracer(__name__)

        # Check that the default tracer creates no-op spans if the sampler
        # decides not to sampler
        root_span = tracer.start_span(name="root span", parent=None)
        self.assertIsInstance(root_span, trace_api.DefaultSpan)
        child_span = tracer.start_span(name="child span", parent=root_span)
        self.assertIsInstance(child_span, trace_api.DefaultSpan)
 def test_tracer(self):
     tracer = trace.TracerSource().get_tracer(__name__)
     with tracer.start_span("test") as span:
         self.assertNotEqual(span.get_context(), INVALID_SPAN_CONTEXT)
         self.assertNotEqual(span, INVALID_SPAN)
         self.assertIs(span.is_recording_events(), True)
         with tracer.start_span("test2") as span2:
             self.assertNotEqual(span2.get_context(), INVALID_SPAN_CONTEXT)
             self.assertNotEqual(span2, INVALID_SPAN)
             self.assertIs(span2.is_recording_events(), True)
Esempio n. 6
0
    def test_span_processor_for_source(self):
        tracer_source = trace.TracerSource()
        tracer1 = tracer_source.get_tracer("instr1")
        tracer2 = tracer_source.get_tracer("instr2", "1.3b3")
        span1 = tracer1.start_span("s1")
        span2 = tracer2.start_span("s2")

        # pylint:disable=protected-access
        self.assertIs(span1.span_processor,
                      tracer_source._active_span_processor)
        self.assertIs(span2.span_processor,
                      tracer_source._active_span_processor)
Esempio n. 7
0
 def test_invalid_instrumentation_info(self):
     tracer_source = trace.TracerSource()
     tracer1 = tracer_source.get_tracer("")
     tracer2 = tracer_source.get_tracer(None)
     self.assertEqual(tracer1.instrumentation_info,
                      tracer2.instrumentation_info)
     self.assertIsInstance(tracer1.instrumentation_info,
                           trace.InstrumentationInfo)
     span1 = tracer1.start_span("foo")
     self.assertTrue(span1.is_recording_events())
     self.assertEqual(tracer1.instrumentation_info.version, "")
     self.assertEqual(tracer1.instrumentation_info.name,
                      "ERROR:MISSING MODULE NAME")
Esempio n. 8
0
    def test_instrumentation_info(self):
        tracer_source = trace.TracerSource()
        tracer1 = tracer_source.get_tracer("instr1")
        tracer2 = tracer_source.get_tracer("instr2", "1.3b3")
        span1 = tracer1.start_span("s1")
        span2 = tracer2.start_span("s2")
        self.assertEqual(span1.instrumentation_info,
                         trace.InstrumentationInfo("instr1", ""))
        self.assertEqual(
            span2.instrumentation_info,
            trace.InstrumentationInfo("instr2", "1.3b3"),
        )

        self.assertEqual(span2.instrumentation_info.version, "1.3b3")
        self.assertEqual(span2.instrumentation_info.name, "instr2")

        self.assertLess(span1.instrumentation_info,
                        span2.instrumentation_info)  # Check sortability.
Esempio n. 9
0
    def test_simple_span_processor(self):
        tracer_source = trace.TracerSource()
        tracer = tracer_source.get_tracer(__name__)

        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.SimpleExportSpanProcessor(my_exporter)
        tracer_source.add_span_processor(span_processor)

        with tracer.start_as_current_span("foo"):
            with tracer.start_as_current_span("bar"):
                with tracer.start_as_current_span("xxx"):
                    pass

        self.assertListEqual(["xxx", "bar", "foo"], spans_names_list)

        span_processor.shutdown()
        self.assertTrue(my_exporter.is_shutdown)
Esempio n. 10
0
    def test_simple_span_processor_no_context(self):
        """Check that we process spans that are never made active.

        SpanProcessors should act on a span's start and end events whether or
        not it is ever the active span.
        """
        tracer_source = trace.TracerSource()
        tracer = tracer_source.get_tracer(__name__)

        spans_names_list = []

        my_exporter = MySpanExporter(destination=spans_names_list)
        span_processor = export.SimpleExportSpanProcessor(my_exporter)
        tracer_source.add_span_processor(span_processor)

        with tracer.start_span("foo"):
            with tracer.start_span("bar"):
                with tracer.start_span("xxx"):
                    pass

        self.assertListEqual(["xxx", "bar", "foo"], spans_names_list)
Esempio n. 11
0
    def test_add_span_processor_after_span_creation(self):
        tracer_source = trace.TracerSource()
        tracer = tracer_source.get_tracer(__name__)

        spans_calls_list = []  # filled by MySpanProcessor
        expected_list = []  # filled by hand

        # Span processors are created but not added to the tracer yet
        sp = MySpanProcessor("SP1", spans_calls_list)

        with tracer.start_as_current_span("foo"):
            with tracer.start_as_current_span("bar"):
                with tracer.start_as_current_span("baz"):
                    # add span processor after spans have been created
                    tracer_source.add_span_processor(sp)

                expected_list.append(span_event_end_fmt("SP1", "baz"))

            expected_list.append(span_event_end_fmt("SP1", "bar"))

        expected_list.append(span_event_end_fmt("SP1", "foo"))

        self.assertListEqual(spans_calls_list, expected_list)
Esempio n. 12
0
    def test_span_processor(self):
        tracer_source = trace.TracerSource()
        tracer = tracer_source.get_tracer(__name__)

        spans_calls_list = []  # filled by MySpanProcessor
        expected_list = []  # filled by hand

        # Span processors are created but not added to the tracer yet
        sp1 = MySpanProcessor("SP1", spans_calls_list)
        sp2 = MySpanProcessor("SP2", spans_calls_list)

        with tracer.start_as_current_span("foo"):
            with tracer.start_as_current_span("bar"):
                with tracer.start_as_current_span("baz"):
                    pass

        # at this point lists must be empty
        self.assertEqual(len(spans_calls_list), 0)

        # add single span processor
        tracer_source.add_span_processor(sp1)

        with tracer.start_as_current_span("foo"):
            expected_list.append(span_event_start_fmt("SP1", "foo"))

            with tracer.start_as_current_span("bar"):
                expected_list.append(span_event_start_fmt("SP1", "bar"))

                with tracer.start_as_current_span("baz"):
                    expected_list.append(span_event_start_fmt("SP1", "baz"))

                expected_list.append(span_event_end_fmt("SP1", "baz"))

            expected_list.append(span_event_end_fmt("SP1", "bar"))

        expected_list.append(span_event_end_fmt("SP1", "foo"))

        self.assertListEqual(spans_calls_list, expected_list)

        spans_calls_list.clear()
        expected_list.clear()

        # go for multiple span processors
        tracer_source.add_span_processor(sp2)

        with tracer.start_as_current_span("foo"):
            expected_list.append(span_event_start_fmt("SP1", "foo"))
            expected_list.append(span_event_start_fmt("SP2", "foo"))

            with tracer.start_as_current_span("bar"):
                expected_list.append(span_event_start_fmt("SP1", "bar"))
                expected_list.append(span_event_start_fmt("SP2", "bar"))

                with tracer.start_as_current_span("baz"):
                    expected_list.append(span_event_start_fmt("SP1", "baz"))
                    expected_list.append(span_event_start_fmt("SP2", "baz"))

                expected_list.append(span_event_end_fmt("SP1", "baz"))
                expected_list.append(span_event_end_fmt("SP2", "baz"))

            expected_list.append(span_event_end_fmt("SP1", "bar"))
            expected_list.append(span_event_end_fmt("SP2", "bar"))

        expected_list.append(span_event_end_fmt("SP1", "foo"))
        expected_list.append(span_event_end_fmt("SP2", "foo"))

        # compare if two lists are the same
        self.assertListEqual(spans_calls_list, expected_list)
Esempio n. 13
0
    def test_shutdown(self):
        tracer_source = trace.TracerSource()

        mock_processor1 = mock.Mock(spec=trace.SpanProcessor)
        tracer_source.add_span_processor(mock_processor1)

        mock_processor2 = mock.Mock(spec=trace.SpanProcessor)
        tracer_source.add_span_processor(mock_processor2)

        tracer_source.shutdown()

        self.assertEqual(mock_processor1.shutdown.call_count, 1)
        self.assertEqual(mock_processor2.shutdown.call_count, 1)

        shutdown_python_code = """
import atexit
from unittest import mock

from opentelemetry.sdk import trace

mock_processor = mock.Mock(spec=trace.SpanProcessor)

def print_shutdown_count():
    print(mock_processor.shutdown.call_count)

# atexit hooks are called in inverse order they are added, so do this before
# creating the tracer
atexit.register(print_shutdown_count)

tracer_source = trace.TracerSource({tracer_parameters})
tracer_source.add_span_processor(mock_processor)

{tracer_shutdown}
"""

        def run_general_code(shutdown_on_exit, explicit_shutdown):
            tracer_parameters = ""
            tracer_shutdown = ""

            if not shutdown_on_exit:
                tracer_parameters = "shutdown_on_exit=False"

            if explicit_shutdown:
                tracer_shutdown = "tracer_source.shutdown()"

            return subprocess.check_output([
                # use shutil to avoid calling python outside the
                # virtualenv on windows.
                shutil.which("python"),
                "-c",
                shutdown_python_code.format(
                    tracer_parameters=tracer_parameters,
                    tracer_shutdown=tracer_shutdown,
                ),
            ])

        # test default shutdown_on_exit (True)
        out = run_general_code(True, False)
        self.assertTrue(out.startswith(b"1"))

        # test that shutdown is called only once even if Tracer.shutdown is
        # called explicitely
        out = run_general_code(True, True)
        self.assertTrue(out.startswith(b"1"))

        # test shutdown_on_exit=False
        out = run_general_code(False, False)
        self.assertTrue(out.startswith(b"0"))
Esempio n. 14
0
def new_tracer() -> trace_api.Tracer:
    return trace.TracerSource().get_tracer(__name__)