def test_remote_endpoint(self): encoder = get_encoder(Encoding.V1_THRIFT) remote_endpoint = create_endpoint(service_name="test_server", host="127.0.0.1") # For server spans, the remote endpoint is encoded as 'ca' binary_annotations = thrift.binary_annotation_list_builder({}, None) encoder.encode_remote_endpoint( remote_endpoint, Kind.SERVER, binary_annotations, ) assert binary_annotations == [ thrift.create_binary_annotation( key="ca", value=thrift.SERVER_ADDR_VAL, annotation_type=thrift.zipkin_core.AnnotationType.BOOL, host=thrift.create_endpoint(0, "test_server", "127.0.0.1", None), ) ] # For client spans, the remote endpoint is encoded as 'sa' binary_annotations = thrift.binary_annotation_list_builder({}, None) encoder.encode_remote_endpoint( remote_endpoint, Kind.CLIENT, binary_annotations, ) assert binary_annotations == [ thrift.create_binary_annotation( key="sa", value=thrift.SERVER_ADDR_VAL, annotation_type=thrift.zipkin_core.AnnotationType.BOOL, host=thrift.create_endpoint(0, "test_server", "127.0.0.1", None), ) ]
def test__convert_from_thrift_binary_annotations_unicode(self): decoder = _V1ThriftDecoder() local_host = thrift.create_endpoint(8888, 'test_service', '10.0.0.1', None) ann_type = zipkin_core.AnnotationType thrift_binary_annotations = [ create_binary_annotation('key1', u'再见', ann_type.STRING, local_host), create_binary_annotation('key2', 'val2', ann_type.STRING, local_host), create_binary_annotation('key3', '再见', ann_type.STRING, local_host), ] tags, local_endpoint, remote_endpoint = \ decoder._convert_from_thrift_binary_annotations( thrift_binary_annotations, ) assert tags == { 'key1': u'再见', 'key2': 'val2', 'key3': '再见', } assert local_endpoint == Endpoint('test_service', '10.0.0.1', None, 8888)
def test_add_sa_binary_annotation(): zipkin_attrs = ZipkinAttrs( trace_id='0', span_id='1', parent_span_id=None, flags='0', is_sampled=True, ) context = zipkin.zipkin_span( service_name='my_service', span_name='span_name', zipkin_attrs=zipkin_attrs, transport_handler=mock.Mock(), port=5, ) with context: assert context.logging_context.sa_binary_annotations == [] context.add_sa_binary_annotation( port=123, service_name='test_service', host='1.2.3.4', ) expected_sa_binary_annotation = create_binary_annotation( key=zipkin_core.SERVER_ADDR, value=SERVER_ADDR_VAL, annotation_type=zipkin_core.AnnotationType.BOOL, host=create_endpoint( port=123, service_name='test_service', host='1.2.3.4', ), ) assert context.logging_context.sa_binary_annotations[0] == \ expected_sa_binary_annotation nested_context = zipkin.zipkin_span( service_name='my_service', span_name='nested_span', ) with nested_context: nested_context.add_sa_binary_annotation( port=456, service_name='nested_service', host='5.6.7.8', ) expected_nested_sa_binary_annotation = create_binary_annotation( key=zipkin_core.SERVER_ADDR, value=SERVER_ADDR_VAL, annotation_type=zipkin_core.AnnotationType.BOOL, host=create_endpoint( port=456, service_name='nested_service', host='5.6.7.8', ), ) assert nested_context.sa_binary_annotations[0] == \ expected_nested_sa_binary_annotation
def generate_single_thrift_span(): trace_id = generate_random_128bit_string() span_id = generate_random_64bit_string() timestamp_s = round(time.time(), 3) duration_s = 2.0 host = thrift.create_endpoint(port=8000, service_name='host') host.ipv4 = 2130706433 span = thrift.create_span( span_id=span_id, parent_span_id=None, trace_id=trace_id, span_name='foo', annotations=[ thrift.create_annotation(1472470996199000, "cs", host), ], binary_annotations=[ thrift.create_binary_annotation( "key", "value", zipkin_core.AnnotationType.STRING, host, ), ], timestamp_s=timestamp_s, duration_s=duration_s, ) return thrift.span_to_bytes(span)
def test_create_binary_annotation(value): bann = thrift.create_binary_annotation("foo", value, "baz", "bla") assert ("foo", value, "baz", "bla") == ( bann.key, bann.value, bann.annotation_type, bann.host, )
def test__convert_from_thrift_binary_annotations(self): decoder = _V1ThriftDecoder() local_host = thrift.create_endpoint(8888, 'test_service', '10.0.0.1', None) remote_host = thrift.create_endpoint(9999, 'rem_service', '10.0.0.2', None) ann_type = zipkin_core.AnnotationType thrift_binary_annotations = [ create_binary_annotation('key1', True, ann_type.BOOL, local_host), create_binary_annotation('key2', 'val2', ann_type.STRING, local_host), create_binary_annotation('key3', False, ann_type.BOOL, local_host), create_binary_annotation('key4', b'04', ann_type.I16, local_host), create_binary_annotation('key5', b'0004', ann_type.I32, local_host), create_binary_annotation('sa', True, ann_type.BOOL, remote_host), ] tags, local_endpoint, remote_endpoint = \ decoder._convert_from_thrift_binary_annotations( thrift_binary_annotations, ) assert tags == { 'key1': 'true', 'key2': 'val2', 'key3': 'false', } assert local_endpoint == Endpoint('test_service', '10.0.0.1', None, 8888) assert remote_endpoint == Endpoint('rem_service', '10.0.0.2', None, 9999)
def test__convert_from_thrift_binary_annotations(self): decoder = _V1ThriftDecoder() local_host = thrift.create_endpoint(8888, "test_service", "10.0.0.1", None) remote_host = thrift.create_endpoint(9999, "rem_service", "10.0.0.2", None) ann_type = zipkin_core.AnnotationType thrift_binary_annotations = [ create_binary_annotation("key1", True, ann_type.BOOL, local_host), create_binary_annotation("key2", "val2", ann_type.STRING, local_host), create_binary_annotation("key3", False, ann_type.BOOL, local_host), create_binary_annotation("key4", b"04", ann_type.I16, local_host), create_binary_annotation("key5", b"0004", ann_type.I32, local_host), create_binary_annotation("sa", True, ann_type.BOOL, remote_host), ] ( tags, local_endpoint, remote_endpoint, ) = decoder._convert_from_thrift_binary_annotations(thrift_binary_annotations) assert tags == { "key1": "true", "key2": "val2", "key3": "false", } assert local_endpoint == Endpoint("test_service", "10.0.0.1", None, 8888) assert remote_endpoint == Endpoint("rem_service", "10.0.0.2", None, 9999)
def test__convert_from_thrift_binary_annotations_unicode(self): decoder = _V1ThriftDecoder() local_host = thrift.create_endpoint(8888, "test_service", "10.0.0.1", None) ann_type = zipkin_core.AnnotationType thrift_binary_annotations = [ create_binary_annotation("key1", u"再见", ann_type.STRING, local_host), create_binary_annotation("key2", "val2", ann_type.STRING, local_host), create_binary_annotation("key3", "再见", ann_type.STRING, local_host), ] ( tags, local_endpoint, remote_endpoint, ) = decoder._convert_from_thrift_binary_annotations(thrift_binary_annotations) assert tags == { "key1": u"再见", "key2": "val2", "key3": "再见", } assert local_endpoint == Endpoint("test_service", "10.0.0.1", None, 8888)
def encode_span(self, span_builder): """Encodes the current span to thrift.""" span = span_builder.build_v1_span() thrift_endpoint = thrift.create_endpoint( span.endpoint.port, span.endpoint.service_name, span.endpoint.ipv4, span.endpoint.ipv6, ) thrift_annotations = thrift.annotation_list_builder( span.annotations, thrift_endpoint, ) thrift_binary_annotations = thrift.binary_annotation_list_builder( span.binary_annotations, thrift_endpoint, ) # Add sa binary annotation if span.sa_endpoint is not None: thrift_sa_endpoint = thrift.create_endpoint( span.sa_endpoint.port, span.sa_endpoint.service_name, span.sa_endpoint.ipv4, span.sa_endpoint.ipv6, ) thrift_binary_annotations.append(thrift.create_binary_annotation( key=thrift.zipkin_core.SERVER_ADDR, value=thrift.SERVER_ADDR_VAL, annotation_type=thrift.zipkin_core.AnnotationType.BOOL, host=thrift_sa_endpoint, )) thrift_span = thrift.create_span( span.id, span.parent_id, span.trace_id, span.name, thrift_annotations, thrift_binary_annotations, span.timestamp, span.duration, ) encoded_span = thrift.span_to_bytes(thrift_span) return encoded_span
def add_sa_binary_annotation( self, port=0, service_name='unknown', host='127.0.0.1', ): """Adds a 'sa' binary annotation to the current span. 'sa' binary annotations are useful for situations where you need to log where a request is going but the destination doesn't support zipkin. Note that the span must have 'cs'/'cr' annotations. :param port: The port number of the destination :type port: int :param service_name: The name of the destination service :type service_name: str :param host: Host address of the destination :type host: str """ if not self.zipkin_attrs or (not self.zipkin_attrs.is_sampled and self.firehose_handler is None): return if 'client' not in self.include: # TODO: trying to set a sa binary annotation for a non-client span # should result in a logged error return sa_endpoint = create_endpoint( port=port, service_name=service_name, host=host, ) sa_binary_annotation = create_binary_annotation( key=zipkin_core.SERVER_ADDR, value=SERVER_ADDR_VAL, annotation_type=zipkin_core.AnnotationType.BOOL, host=sa_endpoint, ) if not self.logging_context: self.sa_binary_annotations.append(sa_binary_annotation) else: self.logging_context.sa_binary_annotations.append( sa_binary_annotation)
def encode_remote_endpoint(self, remote_endpoint, kind, binary_annotations): thrift_remote_endpoint = thrift.create_endpoint( remote_endpoint.port, remote_endpoint.service_name, remote_endpoint.ipv4, remote_endpoint.ipv6, ) if kind == Kind.CLIENT: key = thrift.zipkin_core.SERVER_ADDR elif kind == Kind.SERVER: key = thrift.zipkin_core.CLIENT_ADDR binary_annotations.append( thrift.create_binary_annotation( key=key, value=thrift.SERVER_ADDR_VAL, annotation_type=thrift.zipkin_core.AnnotationType.BOOL, host=thrift_remote_endpoint, ))
def check_v1_thrift(obj, zipkin_attrs, inner_span_id, ts): inner_span, root_span = _decode_binary_thrift_objs(obj) endpoint = thrift.create_endpoint( port=8080, service_name='test_service_name', ipv4='10.0.0.0', ) binary_annotations = thrift.binary_annotation_list_builder( {'some_key': 'some_value'}, endpoint, ) binary_annotations.append(thrift.create_binary_annotation( 'sa', '\x01', zipkin_core.AnnotationType.BOOL, thrift.create_endpoint( port=8888, service_name='sa_service', ipv6='2001:0db8:85a3:0000:0000:8a2e:0370:7334', ), )) expected_root = thrift.create_span( span_id=zipkin_attrs.span_id, parent_span_id=zipkin_attrs.parent_span_id, trace_id=zipkin_attrs.trace_id, span_name='test_span_name', annotations=thrift.annotation_list_builder( OrderedDict([('cs', ts), ('cr', ts + 10)]), endpoint, ), binary_annotations=binary_annotations, timestamp_s=None, duration_s=None, ) # py.test diffs of thrift Spans are pretty useless and hide many things # These prints would only appear on stdout if the test fails and help comparing # the 2 spans. print(root_span) print(expected_root) assert root_span == expected_root expected_inner = thrift.create_span( span_id=inner_span_id, parent_span_id=zipkin_attrs.span_id, trace_id=zipkin_attrs.trace_id, span_name='inner_span', annotations=thrift.annotation_list_builder( OrderedDict([('cs', ts), ('sr', ts), ('ss', ts + 5), ('cr', ts + 5), ('ws', ts)]), endpoint, ), binary_annotations=[], timestamp_s=ts, duration_s=5, ) # py.test diffs of thrift Spans are pretty useless and hide many things # These prints would only appear on stdout if the test fails and help comparing # the 2 spans. print(inner_span) print(expected_inner) assert inner_span == expected_inner
def test_create_binary_annotation(value): bann = thrift.create_binary_annotation('foo', value, 'baz', 'bla') assert ('foo', value, 'baz', 'bla') == (bann.key, bann.value, bann.annotation_type, bann.host)
def check_v1_thrift(obj, zipkin_attrs, inner_span_id, ts): inner_span, producer_span, root_span = _decode_binary_thrift_objs(obj) endpoint = thrift.create_endpoint( port=8080, service_name="test_service_name", ipv4="10.0.0.0", ) binary_annotations = thrift.binary_annotation_list_builder( {"some_key": "some_value"}, endpoint, ) binary_annotations.append( thrift.create_binary_annotation( "sa", "\x01", zipkin_core.AnnotationType.BOOL, thrift.create_endpoint( port=8888, service_name="sa_service", ipv6="2001:0db8:85a3:0000:0000:8a2e:0370:7334", ), ) ) expected_root = thrift.create_span( span_id=zipkin_attrs.span_id, parent_span_id=zipkin_attrs.parent_span_id, trace_id=zipkin_attrs.trace_id, span_name="test_span_name", annotations=thrift.annotation_list_builder( OrderedDict([("cs", ts), ("cr", ts + 10)]), endpoint, ), binary_annotations=binary_annotations, timestamp_s=None, duration_s=None, ) # py.test diffs of thrift Spans are pretty useless and hide many things # These prints would only appear on stdout if the test fails and help comparing # the 2 spans. print(root_span) print(expected_root) assert root_span == expected_root expected_inner = thrift.create_span( span_id=inner_span_id, parent_span_id=zipkin_attrs.span_id, trace_id=zipkin_attrs.trace_id, span_name="inner_span", annotations=thrift.annotation_list_builder( OrderedDict([("ws", ts)]), endpoint, ), binary_annotations=[], timestamp_s=ts, duration_s=5, ) # py.test diffs of thrift Spans are pretty useless and hide many things # These prints would only appear on stdout if the test fails and help comparing # the 2 spans. print(inner_span) print(expected_inner) assert inner_span == expected_inner expected_producer = thrift.create_span( span_id=inner_span_id, parent_span_id=zipkin_attrs.span_id, trace_id=zipkin_attrs.trace_id, span_name="producer_span", annotations=thrift.annotation_list_builder( OrderedDict([("ms", ts)]), endpoint, ), binary_annotations=[], timestamp_s=ts, duration_s=10, ) # py.test diffs of thrift Spans are pretty useless and hide many things # These prints would only appear on stdout if the test fails and help comparing # the 2 spans. print(producer_span) print(expected_producer) assert producer_span == expected_producer
def add_span( self, span_id, parent_span_id, trace_id, span_name, annotations, binary_annotations, timestamp_s, duration_s, endpoint, sa_endpoint, ): thrift_endpoint = thrift.create_endpoint( endpoint.port, endpoint.service_name, endpoint.ipv4, endpoint.ipv6, ) thrift_annotations = thrift.annotation_list_builder( annotations, thrift_endpoint, ) # Binary annotations can be set through debug messages or the # set_extra_binary_annotations registry setting. thrift_binary_annotations = thrift.binary_annotation_list_builder( binary_annotations, thrift_endpoint, ) # Add sa binary annotation if sa_endpoint is not None: thrift_sa_endpoint = thrift.create_endpoint( sa_endpoint.port, sa_endpoint.service_name, sa_endpoint.ipv4, sa_endpoint.ipv6, ) thrift_binary_annotations.append(thrift.create_binary_annotation( key=thrift.zipkin_core.SERVER_ADDR, value=thrift.SERVER_ADDR_VAL, annotation_type=thrift.zipkin_core.AnnotationType.BOOL, host=thrift_sa_endpoint, )) thrift_span = thrift.create_span( span_id, parent_span_id, trace_id, span_name, thrift_annotations, thrift_binary_annotations, timestamp_s, duration_s, ) encoded_span = thrift.span_to_bytes(thrift_span) # If we've already reached the max batch size or the new span doesn't # fit in max_payload_bytes, send what we've collected until now and # start a new batch. is_over_size_limit = ( self.max_payload_bytes is not None and self.current_size + len(encoded_span) > self.max_payload_bytes ) is_over_portion_limit = len(self.queue) >= self.max_portion_size if is_over_size_limit or is_over_portion_limit: self.flush() self.queue.append(encoded_span) self.current_size += len(encoded_span)