Пример #1
0
    def test_events(self):
        self.assertIsNone(self.tracer.get_current_span())

        with self.tracer.start_as_current_span("root") as root:
            # only event name
            root.add_event("event0")

            # event name and attributes
            now = time_ns()
            root.add_event("event1", {"name": "pluto"})

            # event name, attributes and timestamp
            now = time_ns()
            root.add_event("event2", {"name": "birthday"}, now)

            # lazy event
            root.add_lazy_event(
                trace_api.Event("event3", {"name": "hello"}, now))

            self.assertEqual(len(root.events), 4)

            self.assertEqual(root.events[0].name, "event0")
            self.assertEqual(root.events[0].attributes, {})

            self.assertEqual(root.events[1].name, "event1")
            self.assertEqual(root.events[1].attributes, {"name": "pluto"})

            self.assertEqual(root.events[2].name, "event2")
            self.assertEqual(root.events[2].attributes, {"name": "birthday"})
            self.assertEqual(root.events[2].timestamp, now)

            self.assertEqual(root.events[3].name, "event3")
            self.assertEqual(root.events[3].attributes, {"name": "hello"})
            self.assertEqual(root.events[3].timestamp, now)
Пример #2
0
 def add_event(
     self,
     name: str,
     timestamp: int = None,
     attributes: types.Attributes = None,
 ) -> None:
     self.add_lazy_event(
         trace_api.Event(
             name,
             time_ns() if timestamp is None else timestamp,
             Span.empty_attributes if attributes is None else attributes,
         ))
    def test_export(self):

        span_names = ("test1", "test2", "test3")
        trace_id = 0x6E0C63257DE34C926F9EFCD03927272E
        span_id = 0x34BF92DEEFC58C92
        parent_id = 0x1111111111111111
        other_id = 0x2222222222222222

        base_time = 683647322 * 10**9  # in ns
        start_times = (
            base_time,
            base_time + 150 * 10**6,
            base_time + 300 * 10**6,
        )
        durations = (50 * 10**6, 100 * 10**6, 200 * 10**6)
        end_times = (
            start_times[0] + durations[0],
            start_times[1] + durations[1],
            start_times[2] + durations[2],
        )

        span_context = trace_api.SpanContext(
            trace_id,
            span_id,
            trace_options=TraceOptions(TraceOptions.SAMPLED),
        )
        parent_context = trace_api.SpanContext(trace_id, parent_id)
        other_context = trace_api.SpanContext(trace_id, other_id)

        event_attributes = {
            "annotation_bool": True,
            "annotation_string": "annotation_test",
            "key_float": 0.3,
        }

        event_timestamp = base_time + 50 * 10**6
        event = trace_api.Event(
            name="event0",
            timestamp=event_timestamp,
            attributes=event_attributes,
        )

        link_attributes = {"key_bool": True}

        link = trace_api.Link(context=other_context,
                              attributes=link_attributes)

        otel_spans = [
            trace.Span(
                name=span_names[0],
                context=span_context,
                parent=parent_context,
                events=(event, ),
                links=(link, ),
            ),
            trace.Span(name=span_names[1], context=parent_context,
                       parent=None),
            trace.Span(name=span_names[2], context=other_context, parent=None),
        ]

        otel_spans[0].start_time = start_times[0]
        # added here to preserve order
        otel_spans[0].set_attribute("key_bool", False)
        otel_spans[0].set_attribute("key_string", "hello_world")
        otel_spans[0].set_attribute("key_float", 111.22)
        otel_spans[0].end_time = end_times[0]

        otel_spans[1].start_time = start_times[1]
        otel_spans[1].end_time = end_times[1]

        otel_spans[2].start_time = start_times[2]
        otel_spans[2].end_time = end_times[2]

        service_name = "test-service"
        local_endpoint = {
            "serviceName": service_name,
            "port": 9411,
        }

        exporter = ZipkinSpanExporter(service_name)
        expected = [
            {
                "traceId":
                format(trace_id, "x"),
                "id":
                format(span_id, "x"),
                "name":
                span_names[0],
                "timestamp":
                start_times[0] // 10**3,
                "duration":
                durations[0] // 10**3,
                "localEndpoint":
                local_endpoint,
                "kind":
                None,
                "tags": {
                    "key_bool": "False",
                    "key_string": "hello_world",
                    "key_float": "111.22",
                },
                "annotations": [{
                    "timestamp": event_timestamp // 10**3,
                    "value": "event0",
                }],
                "debug":
                1,
                "parentId":
                format(parent_id, "x"),
            },
            {
                "traceId": format(trace_id, "x"),
                "id": format(parent_id, "x"),
                "name": span_names[1],
                "timestamp": start_times[1] // 10**3,
                "duration": durations[1] // 10**3,
                "localEndpoint": local_endpoint,
                "kind": None,
                "tags": None,
                "annotations": None,
            },
            {
                "traceId": format(trace_id, "x"),
                "id": format(other_id, "x"),
                "name": span_names[2],
                "timestamp": start_times[2] // 10**3,
                "duration": durations[2] // 10**3,
                "localEndpoint": local_endpoint,
                "kind": None,
                "tags": None,
                "annotations": None,
            },
        ]

        mock_post = MagicMock()
        with patch("requests.post", mock_post):
            mock_post.return_value = MockResponse(200)
            status = exporter.export(otel_spans)
            self.assertEqual(SpanExportResult.SUCCESS, status)

        mock_post.assert_called_with(
            url="http://localhost:9411/api/v2/spans",
            data=json.dumps(expected),
            headers={"Content-Type": "application/json"},
        )
Пример #4
0
 def add_event(
     self, name: str, attributes: types.Attributes = None
 ) -> None:
     if attributes is None:
         attributes = Span.empty_attributes
     self.add_lazy_event(trace_api.Event(name, util.time_ns(), attributes))
    def test_translate_to_jaeger(self):
        # pylint: disable=invalid-name
        self.maxDiff = None

        span_names = ("test1", "test2", "test3")
        trace_id = 0x6E0C63257DE34C926F9EFCD03927272E
        trace_id_high = 0x6E0C63257DE34C92
        trace_id_low = 0x6F9EFCD03927272E
        span_id = 0x34BF92DEEFC58C92
        parent_id = 0x1111111111111111
        other_id = 0x2222222222222222

        base_time = 683647322 * 10**9  # in ns
        start_times = (
            base_time,
            base_time + 150 * 10**6,
            base_time + 300 * 10**6,
        )
        durations = (50 * 10**6, 100 * 10**6, 200 * 10**6)
        end_times = (
            start_times[0] + durations[0],
            start_times[1] + durations[1],
            start_times[2] + durations[2],
        )

        span_context = trace_api.SpanContext(trace_id,
                                             span_id,
                                             is_remote=False)
        parent_context = trace_api.SpanContext(trace_id,
                                               parent_id,
                                               is_remote=False)
        other_context = trace_api.SpanContext(trace_id,
                                              other_id,
                                              is_remote=False)

        event_attributes = {
            "annotation_bool": True,
            "annotation_string": "annotation_test",
            "key_float": 0.3,
        }

        event_timestamp = base_time + 50 * 10**6
        event = trace_api.Event(
            name="event0",
            timestamp=event_timestamp,
            attributes=event_attributes,
        )

        link_attributes = {"key_bool": True}

        link = trace_api.Link(context=other_context,
                              attributes=link_attributes)

        default_tags = [
            jaeger.Tag(
                key="status.code",
                vType=jaeger.TagType.LONG,
                vLong=StatusCanonicalCode.OK.value,
            ),
            jaeger.Tag(key="status.message",
                       vType=jaeger.TagType.STRING,
                       vStr=None),
            jaeger.Tag(
                key="span.kind",
                vType=jaeger.TagType.STRING,
                vStr=trace_api.SpanKind.INTERNAL.name,
            ),
        ]

        otel_spans = [
            trace.Span(
                name=span_names[0],
                context=span_context,
                parent=parent_context,
                events=(event, ),
                links=(link, ),
                kind=trace_api.SpanKind.CLIENT,
            ),
            trace.Span(name=span_names[1], context=parent_context,
                       parent=None),
            trace.Span(name=span_names[2], context=other_context, parent=None),
        ]

        otel_spans[0].start(start_time=start_times[0])
        # added here to preserve order
        otel_spans[0].set_attribute("key_bool", False)
        otel_spans[0].set_attribute("key_string", "hello_world")
        otel_spans[0].set_attribute("key_float", 111.22)
        otel_spans[0].set_status(
            Status(StatusCanonicalCode.UNKNOWN, "Example description"))
        otel_spans[0].end(end_time=end_times[0])

        otel_spans[1].start(start_time=start_times[1])
        otel_spans[1].end(end_time=end_times[1])

        otel_spans[2].start(start_time=start_times[2])
        otel_spans[2].end(end_time=end_times[2])

        # pylint: disable=protected-access
        spans = jaeger_exporter._translate_to_jaeger(otel_spans)

        expected_spans = [
            jaeger.Span(
                operationName=span_names[0],
                traceIdHigh=trace_id_high,
                traceIdLow=trace_id_low,
                spanId=span_id,
                parentSpanId=parent_id,
                startTime=start_times[0] // 10**3,
                duration=durations[0] // 10**3,
                flags=0,
                tags=[
                    jaeger.Tag(key="key_bool",
                               vType=jaeger.TagType.BOOL,
                               vBool=False),
                    jaeger.Tag(
                        key="key_string",
                        vType=jaeger.TagType.STRING,
                        vStr="hello_world",
                    ),
                    jaeger.Tag(
                        key="key_float",
                        vType=jaeger.TagType.DOUBLE,
                        vDouble=111.22,
                    ),
                    jaeger.Tag(
                        key="status.code",
                        vType=jaeger.TagType.LONG,
                        vLong=StatusCanonicalCode.UNKNOWN.value,
                    ),
                    jaeger.Tag(
                        key="status.message",
                        vType=jaeger.TagType.STRING,
                        vStr="Example description",
                    ),
                    jaeger.Tag(
                        key="span.kind",
                        vType=jaeger.TagType.STRING,
                        vStr=trace_api.SpanKind.CLIENT.name,
                    ),
                    jaeger.Tag(key="error",
                               vType=jaeger.TagType.BOOL,
                               vBool=True),
                ],
                references=[
                    jaeger.SpanRef(
                        refType=jaeger.SpanRefType.FOLLOWS_FROM,
                        traceIdHigh=trace_id_high,
                        traceIdLow=trace_id_low,
                        spanId=other_id,
                    )
                ],
                logs=[
                    jaeger.Log(
                        timestamp=event_timestamp // 10**3,
                        fields=[
                            jaeger.Tag(
                                key="annotation_bool",
                                vType=jaeger.TagType.BOOL,
                                vBool=True,
                            ),
                            jaeger.Tag(
                                key="annotation_string",
                                vType=jaeger.TagType.STRING,
                                vStr="annotation_test",
                            ),
                            jaeger.Tag(
                                key="key_float",
                                vType=jaeger.TagType.DOUBLE,
                                vDouble=0.3,
                            ),
                            jaeger.Tag(
                                key="message",
                                vType=jaeger.TagType.STRING,
                                vStr="event0",
                            ),
                        ],
                    )
                ],
            ),
            jaeger.Span(
                operationName=span_names[1],
                traceIdHigh=trace_id_high,
                traceIdLow=trace_id_low,
                spanId=parent_id,
                parentSpanId=0,
                startTime=start_times[1] // 10**3,
                duration=durations[1] // 10**3,
                flags=0,
                tags=default_tags,
            ),
            jaeger.Span(
                operationName=span_names[2],
                traceIdHigh=trace_id_high,
                traceIdLow=trace_id_low,
                spanId=other_id,
                parentSpanId=0,
                startTime=start_times[2] // 10**3,
                duration=durations[2] // 10**3,
                flags=0,
                tags=default_tags,
            ),
        ]

        # events are complicated to compare because order of fields
        # (attributes) in otel is not important but in jeager it is
        self.assertCountEqual(spans[0].logs[0].fields,
                              expected_spans[0].logs[0].fields)
        # get rid of fields to be able to compare the whole spans
        spans[0].logs[0].fields = None
        expected_spans[0].logs[0].fields = None

        self.assertEqual(spans, expected_spans)
    def test_translate_to_collector(self):
        trace_id = 0x6E0C63257DE34C926F9EFCD03927272E
        span_id = 0x34BF92DEEFC58C92
        parent_id = 0x1111111111111111
        base_time = 683647322 * 10 ** 9  # in ns
        start_times = (
            base_time,
            base_time + 150 * 10 ** 6,
            base_time + 300 * 10 ** 6,
        )
        durations = (50 * 10 ** 6, 100 * 10 ** 6, 200 * 10 ** 6)
        end_times = (
            start_times[0] + durations[0],
            start_times[1] + durations[1],
            start_times[2] + durations[2],
        )
        span_context = trace_api.SpanContext(
            trace_id,
            span_id,
            trace_flags=TraceFlags(TraceFlags.SAMPLED),
            trace_state=trace_api.TraceState({"testKey": "testValue"}),
        )
        parent_context = trace_api.SpanContext(trace_id, parent_id)
        other_context = trace_api.SpanContext(trace_id, span_id)
        event_attributes = {
            "annotation_bool": True,
            "annotation_string": "annotation_test",
            "key_float": 0.3,
        }
        event_timestamp = base_time + 50 * 10 ** 6
        event = trace_api.Event(
            name="event0",
            timestamp=event_timestamp,
            attributes=event_attributes,
        )
        link_attributes = {"key_bool": True}
        link_1 = trace_api.Link(
            context=other_context, attributes=link_attributes
        )
        link_2 = trace_api.Link(
            context=parent_context, attributes=link_attributes
        )
        span_1 = trace.Span(
            name="test1",
            context=span_context,
            parent=parent_context,
            events=(event,),
            links=(link_1,),
            kind=trace_api.SpanKind.CLIENT,
        )
        span_2 = trace.Span(
            name="test2",
            context=parent_context,
            parent=None,
            kind=trace_api.SpanKind.SERVER,
        )
        span_3 = trace.Span(
            name="test3", context=other_context, links=(link_2,), parent=span_2
        )
        otel_spans = [span_1, span_2, span_3]
        otel_spans[0].start(start_time=start_times[0])
        otel_spans[0].set_attribute("key_bool", False)
        otel_spans[0].set_attribute("key_string", "hello_world")
        otel_spans[0].set_attribute("key_float", 111.22)
        otel_spans[0].set_attribute("key_int", 333)
        otel_spans[0].set_status(
            trace_api.Status(
                trace_api.status.StatusCanonicalCode.INTERNAL,
                "test description",
            )
        )
        otel_spans[0].end(end_time=end_times[0])
        otel_spans[1].start(start_time=start_times[1])
        otel_spans[1].end(end_time=end_times[1])
        otel_spans[2].start(start_time=start_times[2])
        otel_spans[2].end(end_time=end_times[2])
        output_spans = translate_to_collector(otel_spans)

        self.assertEqual(len(output_spans), 3)
        self.assertEqual(
            output_spans[0].trace_id, b"n\x0cc%}\xe3L\x92o\x9e\xfc\xd09''."
        )
        self.assertEqual(
            output_spans[0].span_id, b"4\xbf\x92\xde\xef\xc5\x8c\x92"
        )
        self.assertEqual(
            output_spans[0].name, trace_pb2.TruncatableString(value="test1")
        )
        self.assertEqual(
            output_spans[1].name, trace_pb2.TruncatableString(value="test2")
        )
        self.assertEqual(
            output_spans[2].name, trace_pb2.TruncatableString(value="test3")
        )
        self.assertEqual(
            output_spans[0].start_time.seconds,
            int(start_times[0] / 1000000000),
        )
        self.assertEqual(
            output_spans[0].end_time.seconds, int(end_times[0] / 1000000000)
        )
        self.assertEqual(output_spans[0].kind, trace_api.SpanKind.CLIENT.value)
        self.assertEqual(output_spans[1].kind, trace_api.SpanKind.SERVER.value)

        self.assertEqual(
            output_spans[0].parent_span_id, b"\x11\x11\x11\x11\x11\x11\x11\x11"
        )
        self.assertEqual(
            output_spans[2].parent_span_id, b"\x11\x11\x11\x11\x11\x11\x11\x11"
        )
        self.assertEqual(
            output_spans[0].status.code,
            trace_api.status.StatusCanonicalCode.INTERNAL.value,
        )
        self.assertEqual(output_spans[0].status.message, "test description")
        self.assertEqual(len(output_spans[0].tracestate.entries), 1)
        self.assertEqual(output_spans[0].tracestate.entries[0].key, "testKey")
        self.assertEqual(
            output_spans[0].tracestate.entries[0].value, "testValue"
        )

        self.assertEqual(
            output_spans[0].attributes.attribute_map["key_bool"].bool_value,
            False,
        )
        self.assertEqual(
            output_spans[0]
            .attributes.attribute_map["key_string"]
            .string_value.value,
            "hello_world",
        )
        self.assertEqual(
            output_spans[0].attributes.attribute_map["key_float"].double_value,
            111.22,
        )
        self.assertEqual(
            output_spans[0].attributes.attribute_map["key_int"].int_value, 333
        )

        self.assertEqual(
            output_spans[0].time_events.time_event[0].time.seconds, 683647322
        )
        self.assertEqual(
            output_spans[0]
            .time_events.time_event[0]
            .annotation.description.value,
            "event0",
        )
        self.assertEqual(
            output_spans[0]
            .time_events.time_event[0]
            .annotation.attributes.attribute_map["annotation_bool"]
            .bool_value,
            True,
        )
        self.assertEqual(
            output_spans[0]
            .time_events.time_event[0]
            .annotation.attributes.attribute_map["annotation_string"]
            .string_value.value,
            "annotation_test",
        )
        self.assertEqual(
            output_spans[0]
            .time_events.time_event[0]
            .annotation.attributes.attribute_map["key_float"]
            .double_value,
            0.3,
        )

        self.assertEqual(
            output_spans[0].links.link[0].trace_id,
            b"n\x0cc%}\xe3L\x92o\x9e\xfc\xd09''.",
        )
        self.assertEqual(
            output_spans[0].links.link[0].span_id,
            b"4\xbf\x92\xde\xef\xc5\x8c\x92",
        )
        self.assertEqual(
            output_spans[0].links.link[0].type,
            trace_pb2.Span.Link.Type.TYPE_UNSPECIFIED,
        )
        self.assertEqual(
            output_spans[2].links.link[0].type,
            trace_pb2.Span.Link.Type.PARENT_LINKED_SPAN,
        )
        self.assertEqual(
            output_spans[0]
            .links.link[0]
            .attributes.attribute_map["key_bool"]
            .bool_value,
            True,
        )
Пример #7
0
    def test_span_members(self):
        tracer = trace.Tracer("test_span_members")

        other_context1 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )
        other_context2 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )
        other_context3 = trace_api.SpanContext(
            trace_id=trace.generate_trace_id(),
            span_id=trace.generate_span_id(),
        )

        self.assertIsNone(tracer.get_current_span())

        with tracer.start_span("root") as root:
            # attributes
            root.set_attribute("component", "http")
            root.set_attribute("http.method", "GET")
            root.set_attribute("http.url",
                               "https://example.com:779/path/12/?q=d#123")
            root.set_attribute("http.status_code", 200)
            root.set_attribute("http.status_text", "OK")
            root.set_attribute("misc.pi", 3.14)

            # Setting an attribute with the same key as an existing attribute
            # SHOULD overwrite the existing attribute's value.
            root.set_attribute("attr-key", "attr-value1")
            root.set_attribute("attr-key", "attr-value2")

            self.assertEqual(len(root.attributes), 7)
            self.assertEqual(root.attributes["component"], "http")
            self.assertEqual(root.attributes["http.method"], "GET")
            self.assertEqual(
                root.attributes["http.url"],
                "https://example.com:779/path/12/?q=d#123",
            )
            self.assertEqual(root.attributes["http.status_code"], 200)
            self.assertEqual(root.attributes["http.status_text"], "OK")
            self.assertEqual(root.attributes["misc.pi"], 3.14)
            self.assertEqual(root.attributes["attr-key"], "attr-value2")

            # events
            root.add_event("event0")
            root.add_event("event1", {"name": "birthday"})
            now = util.time_ns()
            root.add_lazy_event(
                trace_api.Event("event2", now, {"name": "hello"}))

            self.assertEqual(len(root.events), 3)

            self.assertEqual(root.events[0].name, "event0")
            self.assertEqual(root.events[0].attributes, {})

            self.assertEqual(root.events[1].name, "event1")
            self.assertEqual(root.events[1].attributes, {"name": "birthday"})

            self.assertEqual(root.events[2].name, "event2")
            self.assertEqual(root.events[2].attributes, {"name": "hello"})
            self.assertEqual(root.events[2].timestamp, now)

            # links
            root.add_link(other_context1)
            root.add_link(other_context2, {"name": "neighbor"})
            root.add_lazy_link(
                trace_api.Link(other_context3, {"component": "http"}))

            self.assertEqual(len(root.links), 3)
            self.assertEqual(root.links[0].context.trace_id,
                             other_context1.trace_id)
            self.assertEqual(root.links[0].context.span_id,
                             other_context1.span_id)
            self.assertEqual(root.links[0].attributes, {})
            self.assertEqual(root.links[1].context.trace_id,
                             other_context2.trace_id)
            self.assertEqual(root.links[1].context.span_id,
                             other_context2.span_id)
            self.assertEqual(root.links[1].attributes, {"name": "neighbor"})
            self.assertEqual(root.links[2].context.span_id,
                             other_context3.span_id)
            self.assertEqual(root.links[2].attributes, {"component": "http"})

            # name
            root.update_name("toor")
            self.assertEqual(root.name, "toor")