예제 #1
0
def format_span_json(span):
    """Helper to format a Span in JSON format.

    :type span: :class:`~opencensus.trace.span.Span`
    :param span: A Span to be transferred to JSON format.

    :rtype: dict
    :returns: Formatted Span.
    """
    span_json = {
        'displayName': utils.get_truncatable_str(span.name),
        'spanId': span.span_id,
        'startTime': span.start_time,
        'endTime': span.end_time,
        'childSpanCount': len(span._child_spans)
    }

    parent_span_id = None

    if span.parent_span is not None:
        parent_span_id = span.parent_span.span_id

    if parent_span_id is not None:
        span_json['parentSpanId'] = parent_span_id

    if span.attributes:
        span_json['attributes'] = attributes_module.Attributes(
            span.attributes).format_attributes_json()

    if span.stack_trace is not None:
        span_json['stackTrace'] = span.stack_trace.format_stack_trace_json()

    formatted_time_events = []
    if span.annotations:
        formatted_time_events.extend({
            'time': aa.timestamp,
            'annotation': aa.format_annotation_json()
        } for aa in span.annotations)
    if span.message_events:
        formatted_time_events.extend(
            {
                'time': aa.timestamp,
                'message_event': aa.format_message_event_json()
            } for aa in span.message_events)
    if formatted_time_events:
        span_json['timeEvents'] = {'timeEvent': formatted_time_events}

    if span.links:
        span_json['links'] = {
            'link': [link.format_link_json() for link in span.links]
        }

    if span.status is not None:
        span_json['status'] = span.status.format_status_json()

    if span.same_process_as_parent_span is not None:
        span_json['sameProcessAsParentSpan'] = \
            span.same_process_as_parent_span

    return span_json
예제 #2
0
    def test_format_attributes_json(self):
        attrs = {
            'key1': 'test string',
            'key2': True,
            'key3': 100,
        }

        attributes = attributes_module.Attributes(attrs)
        attributes_json = attributes.format_attributes_json()

        expected_attributes_json = {
            'attributeMap': {
                'key1': {
                    'string_value': {
                        'value': 'test string',
                        'truncated_byte_count': 0
                    }
                },
                'key2': {
                    'bool_value': True
                },
                'key3': {
                    'int_value': 100
                }
            }
        }

        self.assertEqual(expected_attributes_json, attributes_json)
예제 #3
0
    def test_set_annotation_with_attributes(self):
        pb_span = trace_pb2.Span()
        pb_event = pb_span.time_events.time_event.add()

        annotation = time_event_module.Annotation(
            description="hi there",
            attributes=attributes_module.Attributes(
                attributes={
                    'test_str_key': 'test_str_value',
                    'test_int_key': 1,
                    'test_bool_key': False,
                    'test_double_key': 567.89
                }))

        utils.set_proto_annotation(pb_event.annotation, annotation)

        self.assertEqual(pb_event.annotation.description.value, "hi there")
        self.assertEqual(len(pb_event.annotation.attributes.attribute_map), 4)
        self.assertEqual(
            pb_event.annotation.attributes.attribute_map['test_str_key'],
            trace_pb2.AttributeValue(string_value=trace_pb2.TruncatableString(
                value='test_str_value')))
        self.assertEqual(
            pb_event.annotation.attributes.attribute_map['test_int_key'],
            trace_pb2.AttributeValue(int_value=1))
        self.assertEqual(
            pb_event.annotation.attributes.attribute_map['test_bool_key'],
            trace_pb2.AttributeValue(bool_value=False))
        self.assertEqual(
            pb_event.annotation.attributes.attribute_map['test_double_key'],
            trace_pb2.AttributeValue(double_value=567.89))
예제 #4
0
    def test_set_attribute(self):
        key = 'test key'
        value = 'test value'
        attributes = attributes_module.Attributes()
        attributes.set_attribute(key=key, value=value)

        expected_attr = {key: value}

        self.assertEqual(expected_attr, attributes.attributes)
예제 #5
0
    def test_format_attributes_json_type_error(self):
        attrs = {
            'key1': mock.Mock(),
        }

        expected_json = {'attributeMap': {}}

        attributes = attributes_module.Attributes(attrs)
        attributes_json = attributes.format_attributes_json()

        self.assertEqual(attributes_json, expected_json)
예제 #6
0
def _format_legacy_span_json(span_data):
    """
    :param SpanData span_data: SpanData object to convert
    :rtype: dict
    :return: Dictionary representing the Span
    """
    span_json = {
        'displayName': utils.get_truncatable_str(span_data.name),
        'spanId': span_data.span_id,
        'startTime': span_data.start_time,
        'endTime': span_data.end_time,
        'childSpanCount': span_data.child_span_count,
        'kind': span_data.span_kind
    }

    if span_data.parent_span_id is not None:
        span_json['parentSpanId'] = span_data.parent_span_id

    if span_data.attributes:
        span_json['attributes'] = attributes.Attributes(
            span_data.attributes).format_attributes_json()

    if span_data.stack_trace is not None:
        span_json['stackTrace'] = \
            span_data.stack_trace.format_stack_trace_json()

    formatted_time_events = []
    if span_data.annotations:
        formatted_time_events.extend({
            'time': aa.timestamp,
            'annotation': aa.format_annotation_json()
        } for aa in span_data.annotations)
    if span_data.message_events:
        formatted_time_events.extend(
            {
                'time': aa.timestamp,
                'message_event': aa.format_message_event_json()
            } for aa in span_data.message_events)
    if formatted_time_events:
        span_json['timeEvents'] = {'timeEvent': formatted_time_events}

    if span_data.links:
        span_json['links'] = {
            'link': [link.format_link_json() for link in span_data.links]
        }

    if span_data.status is not None:
        span_json['status'] = span_data.status.format_status_json()

    if span_data.same_process_as_parent_span is not None:
        span_json['sameProcessAsParentSpan'] = \
            span_data.same_process_as_parent_span

    return span_json
예제 #7
0
    def add_annotation(self, description, **attrs):
        """Add an annotation to span.

        :type description: str
        :param description: A user-supplied message describing the event.
                        The maximum length for the description is 256 bytes.

        :type attrs: kwargs
        :param attrs: keyworded arguments e.g. failed=True, name='Caching'
        """
        at = attributes.Attributes(attrs)
        self.add_time_event(time_event_module.TimeEvent(datetime.utcnow(),
                            time_event_module.Annotation(description, at)))
예제 #8
0
    def test_set_annotation_without_attributes(self):
        pb_span = trace_pb2.Span()
        pb_event0 = pb_span.time_events.time_event.add()
        pb_event1 = pb_span.time_events.time_event.add()

        annotation0 = time_event_module.Annotation(description="hi there0")
        annotation1 = time_event_module.Annotation(
            description="hi there1", attributes=attributes_module.Attributes())

        utils.set_proto_annotation(pb_event0.annotation, annotation0)
        utils.set_proto_annotation(pb_event1.annotation, annotation1)

        self.assertEqual(pb_event0.annotation.description.value, "hi there0")
        self.assertEqual(pb_event1.annotation.description.value, "hi there1")
        self.assertEqual(len(pb_event0.annotation.attributes.attribute_map), 0)
        self.assertEqual(len(pb_event1.annotation.attributes.attribute_map), 0)
예제 #9
0
    def test_get_attribute(self):
        attr = {'key': 'value'}
        attributes = attributes_module.Attributes(attr)
        value = attributes.get_attribute('key')

        self.assertEqual(value, 'value')
예제 #10
0
    def test_delete_attribute(self):
        attr = {'key1': 'value1', 'key2': 'value2'}
        attributes = attributes_module.Attributes(attr)
        attributes.delete_attribute('key1')

        self.assertEqual(attributes.attributes, {'key2': 'value2'})
예제 #11
0
    def test_constructor_explicit(self):
        attr = {'key': 'value'}
        attributes = attributes_module.Attributes(attr)

        self.assertEqual(attributes.attributes, attr)
예제 #12
0
 def test_constructor_default(self):
     attributes = attributes_module.Attributes()
     self.assertEqual(attributes.attributes, {})
    def test_translate_to_jaeger(self):
        self.maxDiff = None
        trace_id_high = '6e0c63257de34c92'
        trace_id_low = 'bf9efcd03927272e'
        trace_id = trace_id_high + trace_id_low
        span_id = '6e0c63257de34c92'
        parent_span_id = '1111111111111111'

        span_attributes = {
            'key_bool': False,
            'key_string': 'hello_world',
            'key_int': 3
        }

        annotation_attributes = {
            'annotation_bool': True,
            'annotation_string': 'annotation_test',
            'key_float': .3
        }

        link_attributes = {'key_bool': True}

        import datetime
        s = '2017-08-15T18:02:26.071158'
        time = datetime.datetime.strptime(s, '%Y-%m-%dT%H:%M:%S.%f')
        time_events = [
            time_event.TimeEvent(
                timestamp=time,
                annotation=time_event.Annotation(
                    description='First Annotation',
                    attributes=attributes.Attributes(annotation_attributes))),
            time_event.TimeEvent(timestamp=time,
                                 message_event=time_event.MessageEvent(
                                     id='message-event-id',
                                     uncompressed_size_bytes=0,
                                 )),
        ]

        time_events2 = [
            time_event.TimeEvent(timestamp=time,
                                 annotation=time_event.Annotation(
                                     description='First Annotation',
                                     attributes=None)),
            time_event.TimeEvent(timestamp=time,
                                 message_event=time_event.MessageEvent(
                                     id='message-event-id',
                                     uncompressed_size_bytes=0,
                                 )),
        ]

        links = [
            link.Link(trace_id=trace_id,
                      span_id=span_id,
                      type=link.Type.CHILD_LINKED_SPAN,
                      attributes=link_attributes),
            link.Link(trace_id=trace_id,
                      span_id=span_id,
                      type=link.Type.PARENT_LINKED_SPAN,
                      attributes=link_attributes),
            link.Link(trace_id=trace_id,
                      span_id=span_id,
                      type=link.Type.TYPE_UNSPECIFIED,
                      attributes=link_attributes)
        ]

        span_status = status.Status(code=200, message='success')

        start_time = '2017-08-15T18:02:26.071158Z'
        end_time = '2017-08-15T18:02:36.071158Z'

        span_datas = [
            span_data.SpanData(
                name='test1',
                context=span_context.SpanContext(trace_id=trace_id),
                span_id=span_id,
                parent_span_id=parent_span_id,
                attributes=span_attributes,
                start_time=start_time,
                end_time=end_time,
                child_span_count=0,
                stack_trace=None,
                time_events=time_events,
                links=links,
                status=span_status,
                same_process_as_parent_span=None,
                span_kind=0,
            ),
            span_data.SpanData(
                name='test2',
                context=None,
                span_id=span_id,
                parent_span_id=None,
                attributes=None,
                start_time=start_time,
                end_time=end_time,
                child_span_count=None,
                stack_trace=None,
                time_events=time_events2,
                links=None,
                status=None,
                same_process_as_parent_span=None,
                span_kind=None,
            ),
            span_data.SpanData(
                name='test3',
                context=None,
                span_id=span_id,
                parent_span_id=None,
                attributes=None,
                start_time=start_time,
                end_time=end_time,
                child_span_count=None,
                stack_trace=None,
                time_events=None,
                links=None,
                status=None,
                same_process_as_parent_span=None,
                span_kind=None,
            )
        ]

        exporter = jaeger_exporter.JaegerExporter()

        spans = exporter.translate_to_jaeger(span_datas)
        expected_spans = [
            jaeger.Span(
                traceIdHigh=7929822056569588882,
                traceIdLow=-4638992594902767826,
                spanId=7929822056569588882,
                parentSpanId=1229782938247303441,
                operationName='test1',
                startTime=1502820146071158,
                duration=10000000,
                flags=1,
                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_int',
                               vType=jaeger.TagType.LONG,
                               vLong=3),
                    jaeger.Tag(key='status.code',
                               vType=jaeger.TagType.LONG,
                               vLong=200),
                    jaeger.Tag(key='status.message',
                               vType=jaeger.TagType.STRING,
                               vStr='success')
                ],
                references=[
                    jaeger.SpanRef(refType=jaeger.SpanRefType.CHILD_OF,
                                   traceIdHigh=7929822056569588882,
                                   traceIdLow=-4638992594902767826,
                                   spanId=7929822056569588882),
                    jaeger.SpanRef(refType=jaeger.SpanRefType.FOLLOWS_FROM,
                                   traceIdHigh=7929822056569588882,
                                   traceIdLow=-4638992594902767826,
                                   spanId=7929822056569588882),
                    jaeger.SpanRef(refType=None,
                                   traceIdHigh=7929822056569588882,
                                   traceIdLow=-4638992594902767826,
                                   spanId=7929822056569588882)
                ],
                logs=[
                    jaeger.Log(timestamp=1502820146071158,
                               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='message',
                                              vType=jaeger.TagType.STRING,
                                              vStr='First Annotation')
                               ])
                ]),
            jaeger.Span(operationName="test2",
                        traceIdHigh=7929822056569588882,
                        traceIdLow=-4638992594902767826,
                        spanId=7929822056569588882,
                        parentSpanId=0,
                        startTime=1502820146071158,
                        duration=10000000,
                        logs=[
                            jaeger.Log(timestamp=1502820146071158,
                                       fields=[
                                           jaeger.Tag(
                                               key='message',
                                               vType=jaeger.TagType.STRING,
                                               vStr='First Annotation')
                                       ])
                        ]),
            jaeger.Span(operationName="test3",
                        traceIdHigh=7929822056569588882,
                        traceIdLow=-4638992594902767826,
                        spanId=7929822056569588882,
                        parentSpanId=0,
                        startTime=1502820146071158,
                        duration=10000000,
                        logs=[])
        ]

        spans_json = [span.format_span_json() for span in spans]
        expected_spans_json = [
            span.format_span_json() for span in expected_spans
        ]
        span = spans_json[0]
        expected_span = expected_spans_json[0]

        try:
            listsEqual = self.assertCountEqual
        except AttributeError:
            listsEqual = self.assertItemsEqual

        log = span.get('logs')[0]
        expected_log = expected_span.get('logs')[0]
        self.assertEqual(log.get('timestamp'), expected_log.get('timestamp'))
        listsEqual(log.get('fields'), expected_log.get('fields'))
        listsEqual(span.get('tags'), expected_span.get('tags'))
        listsEqual(span.get('references'), expected_span.get('references'))
        self.assertEqual(span.get('traceIdHigh'),
                         expected_span.get('traceIdHigh'))
        self.assertEqual(span.get('traceIdLow'),
                         expected_span.get('traceIdLow'))
        self.assertEqual(span.get('spanId'), expected_span.get('spanId'))
        self.assertEqual(span.get('parentSpanId'),
                         expected_span.get('parentSpanId'))
        self.assertEqual(span.get('operationName'),
                         expected_span.get('operationName'))
        self.assertEqual(span.get('startTime'), expected_span.get('startTime'))
        self.assertEqual(span.get('duration'), expected_span.get('duration'))
        self.assertEqual(span.get('flags'), expected_span.get('flags'))
        self.assertEqual(spans_json[1], expected_spans_json[1])

        self.assertEqual(spans_json[2], expected_spans_json[2])
예제 #14
0
    def test_translate_time_events(self):

        annotation0_ts = datetime.utcnow() + timedelta(seconds=-10)
        annotation1_ts = datetime.utcnow() + timedelta(seconds=-9)
        message0_ts = datetime.utcnow() + timedelta(seconds=-8)
        message1_ts = datetime.utcnow() + timedelta(seconds=-7)
        message2_ts = datetime.utcnow() + timedelta(seconds=-6)

        span_data = span_data_module.SpanData(
            context=span_context_module.SpanContext(
                trace_id='6e0c63257de34c92bf9efcd03927272e'),
            span_id='6e0c63257de34c92',
            time_events=[
                time_event_module.TimeEvent(
                    timestamp=annotation0_ts,
                    annotation=time_event_module.Annotation(
                        description="hi there0",
                        attributes=attributes_module.Attributes(
                            attributes={
                                'test_str_key': 'test_str_value',
                                'test_int_key': 1,
                                'test_bool_key': False,
                                'test_double_key': 567.89
                            }))),
                time_event_module.TimeEvent(
                    timestamp=annotation1_ts,
                    annotation=time_event_module.Annotation(
                        description="hi there1")),
                time_event_module.TimeEvent(
                    timestamp=message0_ts,
                    message_event=time_event_module.MessageEvent(
                        id=0,
                        type=time_event_module.Type.SENT,
                        uncompressed_size_bytes=10,
                        compressed_size_bytes=1)),
                time_event_module.TimeEvent(
                    timestamp=message1_ts,
                    message_event=time_event_module.MessageEvent(
                        id=1,
                        type=time_event_module.Type.RECEIVED,
                        uncompressed_size_bytes=20,
                        compressed_size_bytes=2)),
                time_event_module.TimeEvent(
                    timestamp=message2_ts,
                    message_event=time_event_module.MessageEvent(
                        id=2,
                        type=time_event_module.Type.TYPE_UNSPECIFIED,
                        uncompressed_size_bytes=30,
                        compressed_size_bytes=3))
            ],
            span_kind=span_module.SpanKind.SERVER,
            status=None,
            start_time=None,
            end_time=None,
            child_span_count=None,
            name=None,
            parent_span_id=None,
            attributes=None,
            same_process_as_parent_span=False,
            stack_trace=None,
            links=None)

        pb_span = utils.translate_to_trace_proto(span_data)

        self.assertEqual(len(pb_span.time_events.time_event), 5)

        event0 = pb_span.time_events.time_event[0]
        event1 = pb_span.time_events.time_event[1]
        event2 = pb_span.time_events.time_event[2]
        event3 = pb_span.time_events.time_event[3]
        event4 = pb_span.time_events.time_event[4]
        self.assertEqual(event0.time.ToDatetime(), annotation0_ts)
        self.assertEqual(event1.time.ToDatetime(), annotation1_ts)
        self.assertEqual(event2.time.ToDatetime(), message0_ts)
        self.assertEqual(event3.time.ToDatetime(), message1_ts)
        self.assertEqual(event4.time.ToDatetime(), message2_ts)

        self.assertEqual(event0.annotation.description.value, "hi there0")
        self.assertEqual(event1.annotation.description.value, "hi there1")

        self.assertEqual(len(event0.annotation.attributes.attribute_map), 4)
        self.assertEqual(len(event1.annotation.attributes.attribute_map), 0)

        self.assertEqual(
            event0.annotation.attributes.attribute_map['test_str_key'],
            trace_pb2.AttributeValue(string_value=trace_pb2.TruncatableString(
                value='test_str_value')))

        self.assertEqual(
            event0.annotation.attributes.attribute_map['test_int_key'],
            trace_pb2.AttributeValue(int_value=1))
        self.assertEqual(
            event0.annotation.attributes.attribute_map['test_bool_key'],
            trace_pb2.AttributeValue(bool_value=False))
        self.assertEqual(
            event0.annotation.attributes.attribute_map['test_double_key'],
            trace_pb2.AttributeValue(double_value=567.89))

        self.assertEqual(event2.message_event.id, 0)
        self.assertEqual(event3.message_event.id, 1)
        self.assertEqual(event4.message_event.id, 2)

        self.assertEqual(event2.message_event.uncompressed_size, 10)
        self.assertEqual(event3.message_event.uncompressed_size, 20)
        self.assertEqual(event4.message_event.uncompressed_size, 30)

        self.assertEqual(event2.message_event.compressed_size, 1)
        self.assertEqual(event3.message_event.compressed_size, 2)
        self.assertEqual(event4.message_event.compressed_size, 3)

        self.assertEqual(event2.message_event.type, 1)
        self.assertEqual(event3.message_event.type, 2)
        self.assertEqual(event4.message_event.type, 0)
예제 #15
0
    def test_translate_links(self):
        hex_encoder = codecs.getencoder('hex')

        span_data = span_data_module.SpanData(
            context=span_context_module.SpanContext(
                trace_id='6e0c63257de34c92bf9efcd03927272e'),
            span_id='6e0c63257de34c92',
            links=[
                link_module.Link(trace_id='0e0c63257de34c92bf9efcd03927272e',
                                 span_id='0e0c63257de34c92',
                                 type=link_module.Type.TYPE_UNSPECIFIED,
                                 attributes=attributes_module.Attributes(
                                     attributes={
                                         'test_str_key': 'test_str_value',
                                         'test_int_key': 1,
                                         'test_bool_key': False,
                                         'test_double_key': 567.89
                                     })),
                link_module.Link(trace_id='1e0c63257de34c92bf9efcd03927272e',
                                 span_id='1e0c63257de34c92',
                                 type=link_module.Type.CHILD_LINKED_SPAN),
                link_module.Link(trace_id='2e0c63257de34c92bf9efcd03927272e',
                                 span_id='2e0c63257de34c92',
                                 type=link_module.Type.PARENT_LINKED_SPAN)
            ],
            span_kind=span_module.SpanKind.SERVER,
            status=None,
            start_time=None,
            end_time=None,
            child_span_count=None,
            name=None,
            parent_span_id=None,
            attributes=None,
            same_process_as_parent_span=False,
            stack_trace=None,
            time_events=None)

        pb_span = utils.translate_to_trace_proto(span_data)

        self.assertEqual(len(pb_span.links.link), 3)
        self.assertEqual(
            hex_encoder(pb_span.links.link[0].trace_id)[0],
            b'0e0c63257de34c92bf9efcd03927272e')
        self.assertEqual(
            hex_encoder(pb_span.links.link[1].trace_id)[0],
            b'1e0c63257de34c92bf9efcd03927272e')
        self.assertEqual(
            hex_encoder(pb_span.links.link[2].trace_id)[0],
            b'2e0c63257de34c92bf9efcd03927272e')

        self.assertEqual(
            hex_encoder(pb_span.links.link[0].span_id)[0], b'0e0c63257de34c92')
        self.assertEqual(
            hex_encoder(pb_span.links.link[1].span_id)[0], b'1e0c63257de34c92')
        self.assertEqual(
            hex_encoder(pb_span.links.link[2].span_id)[0], b'2e0c63257de34c92')

        self.assertEqual(pb_span.links.link[0].type, 0)
        self.assertEqual(pb_span.links.link[1].type, 1)
        self.assertEqual(pb_span.links.link[2].type, 2)

        self.assertEqual(len(pb_span.links.link[0].attributes.attribute_map),
                         4)
        self.assertEqual(len(pb_span.links.link[1].attributes.attribute_map),
                         0)
        self.assertEqual(len(pb_span.links.link[2].attributes.attribute_map),
                         0)

        self.assertEqual(
            pb_span.links.link[0].attributes.attribute_map['test_str_key'],
            trace_pb2.AttributeValue(string_value=trace_pb2.TruncatableString(
                value='test_str_value')))

        self.assertEqual(
            pb_span.links.link[0].attributes.attribute_map['test_int_key'],
            trace_pb2.AttributeValue(int_value=1))
        self.assertEqual(
            pb_span.links.link[0].attributes.attribute_map['test_bool_key'],
            trace_pb2.AttributeValue(bool_value=False))
        self.assertEqual(
            pb_span.links.link[0].attributes.attribute_map['test_double_key'],
            trace_pb2.AttributeValue(double_value=567.89))