def log_spans(self): """Main function to log all the annotations stored during the entire request. This is done if the request is sampled and the response was a success. It also logs the service `ss` and `sr` annotations. """ if self.zipkin_attrs.is_sampled and self.is_response_success(): for span in self.handler.spans: # If a logged client span overrode the 'service_name' attr, # swap that out. if span['service_name'] is None: endpoint = self.thrift_endpoint else: endpoint = copy_endpoint_with_new_service_name( self.thrift_endpoint, span['service_name'] ) annotations = annotation_list_builder( span['annotations'], endpoint) binary_annotations = binary_annotation_list_builder( span['binary_annotations'], endpoint) log_span(self.zipkin_attrs, span['span_name'], self.registry_settings, annotations, binary_annotations, span['is_client']) end_timestamp = time.time() log_service_span(self.zipkin_attrs, self.start_timestamp, end_timestamp, self.binary_annotations_dict, self.thrift_endpoint, self.request_method, self.registry_settings)
def log_service_span(zipkin_attrs, start_timestamp, end_timestamp, binary_annotations_dict, thrift_endpoint, method, registry_settings): """Logs a span with `ss` and `sr` annotations. """ annotations = annotation_list_builder( {'sr': start_timestamp, 'ss': end_timestamp}, thrift_endpoint) binary_annotations = binary_annotation_list_builder( binary_annotations_dict, thrift_endpoint) log_span(zipkin_attrs, method, registry_settings, annotations, binary_annotations, False)
def log_spans(self): """Main function to log all the annotations stored during the entire request. This is done if the request is sampled and the response was a success. It also logs the service `ss` and `sr` annotations. """ if self.zipkin_attrs.is_sampled and self.is_response_success(): for _, span in self.handler.spans.items(): annotations = annotation_list_builder( span['annotations'], self.endpoint_attrs) binary_annotations = binary_annotation_list_builder( span['binary_annotations'], self.endpoint_attrs) log_span(self.zipkin_attrs, span['span_name'], self.registry_settings, annotations, binary_annotations, span['is_client']) end_timestamp = time.time() log_service_span(self.zipkin_attrs, self.start_timestamp, end_timestamp, self.binary_annotations_dict, self.endpoint_attrs, self.request_method, self.registry_settings)
def log_spans(self): """Main function to log all the annotations stored during the entire request. This is done if the request is sampled and the response was a success. It also logs the service `ss` and `sr` annotations. """ if self.zipkin_attrs.is_sampled and self.is_response_success(): for _, span in self.handler.spans.items(): annotations = annotation_list_builder(span['annotations'], self.endpoint_attrs) binary_annotations = binary_annotation_list_builder( span['binary_annotations'], self.endpoint_attrs) log_span(self.zipkin_attrs, span['span_name'], self.registry_settings, annotations, binary_annotations, span['is_client']) end_timestamp = time.time() log_service_span(self.zipkin_attrs, self.start_timestamp, end_timestamp, self.binary_annotations_dict, self.endpoint_attrs, self.request_method, self.registry_settings)
def log_spans(self): """Main function to log all the annotations stored during the entire request. This is done if the request is sampled and the response was a success. It also logs the service `ss` and `sr` annotations. """ if self.zipkin_attrs.is_sampled and self.is_response_success(): # Collect additional annotations from the logging handler annotations_by_span_id = defaultdict(dict) binary_annotations_by_span_id = defaultdict(dict) for msg in self.handler.extra_annotations: span_id = msg['parent_span_id'] or self.zipkin_attrs.span_id # This should check if these are non-None annotations_by_span_id[span_id].update(msg['annotations']) binary_annotations_by_span_id[span_id].update( msg['binary_annotations'] ) # Collect, annotate, and log client spans from the logging handler for span in self.handler.client_spans: # The parent_span_id is either the parent ID set in the # logging handler or the current Zipkin context's span ID. parent_span_id = ( span['parent_span_id'] or self.zipkin_attrs.span_id ) # A new client span's span ID can be overridden span_id = span['span_id'] or generate_random_64bit_string() endpoint = copy_endpoint_with_new_service_name( self.thrift_endpoint, span['service_name'] ) # Collect annotations both logged with the new spans and # logged in separate log messages. annotations = span['annotations'] annotations.update(annotations_by_span_id[span_id]) binary_annotations = span['binary_annotations'] binary_annotations.update(binary_annotations_by_span_id[span_id]) # Create serializable thrift objects of annotations thrift_annotations = annotation_list_builder( annotations, endpoint ) thrift_binary_annotations = binary_annotation_list_builder( binary_annotations, endpoint ) log_span( span_id=span_id, parent_span_id=parent_span_id, trace_id=self.zipkin_attrs.trace_id, span_name=span['span_name'], annotations=thrift_annotations, binary_annotations=thrift_binary_annotations, registry_settings=self.registry_settings, ) # Collect extra annotations for server span, then log it. extra_annotations = annotations_by_span_id[self.zipkin_attrs.span_id] extra_binary_annotations = binary_annotations_by_span_id[ self.zipkin_attrs.span_id ] annotations = dict( sr=self.start_timestamp, ss=time.time(), **extra_annotations ) thrift_annotations = annotation_list_builder( annotations, self.thrift_endpoint, ) # Binary annotations can be set through debug messages or the # set_extra_binary_annotations registry setting. self.binary_annotations_dict.update(extra_binary_annotations) thrift_binary_annotations = binary_annotation_list_builder( self.binary_annotations_dict, self.thrift_endpoint, ) span_name = "{0} {1}".format( self.request_method, self.request_path) log_span( span_id=self.zipkin_attrs.span_id, parent_span_id=self.zipkin_attrs.parent_span_id, trace_id=self.zipkin_attrs.trace_id, span_name=span_name, annotations=thrift_annotations, binary_annotations=thrift_binary_annotations, registry_settings=self.registry_settings, )
def test_annotation_list_builder(ann_mock): ann_list = {'foo': 1, 'bar': 2} thrift_helper.annotation_list_builder(ann_list, 'host') ann_mock.assert_any_call(1000000, 'foo', 'host') ann_mock.assert_any_call(2000000, 'bar', 'host') assert ann_mock.call_count == 2
def test_annotation_list_builder(ann_mock): ann_list = {"foo": 1, "bar": 2} thrift_helper.annotation_list_builder(ann_list, "host") ann_mock.assert_any_call(1000000, "foo", "host") ann_mock.assert_any_call(2000000, "bar", "host") assert ann_mock.call_count == 2