def test_format_legacy_trace_json(self): trace_id = '2dd43a1d6b2549c6bc2a1a54c2fc0b05' span_data = span_data_module.SpanData( name='root', context=span_context.SpanContext(trace_id=trace_id, span_id='6e0c63257de34c92'), span_id='6e0c63257de34c92', parent_span_id='6e0c63257de34c93', attributes={'key1': 'value1'}, start_time=utils.to_iso_str(), end_time=utils.to_iso_str(), stack_trace=stack_trace.StackTrace(stack_trace_hash_id='111'), links=[link.Link('1111', span_id='6e0c63257de34c92')], status=status.Status(code=0, message='pok'), annotations=[ time_event.Annotation(timestamp=datetime.datetime(1970, 1, 1), description='description') ], message_events=[ time_event.MessageEvent( timestamp=datetime.datetime(1970, 1, 1), id=0, ) ], same_process_as_parent_span=False, child_span_count=0, span_kind=0, ) trace_json = span_data_module.format_legacy_trace_json([span_data]) self.assertEqual(trace_json.get('traceId'), trace_id) self.assertEqual(len(trace_json.get('spans')), 1)
def _trace_db_call(execute, sql, params, many, context): tracer = _get_current_tracer() if not tracer: return execute(sql, params, many, context) vendor = context['connection'].vendor alias = context['connection'].alias span = tracer.start_span() span.name = '{}.query'.format(vendor) span.span_kind = span_module.SpanKind.CLIENT tracer.add_attribute_to_current_span('component', vendor) tracer.add_attribute_to_current_span('db.instance', alias) tracer.add_attribute_to_current_span('db.statement', sql) tracer.add_attribute_to_current_span('db.type', 'sql') try: result = execute(sql, params, many, context) except Exception: # pragma: NO COVER status = status_module.Status(code=code_pb2.UNKNOWN, message='DB error') span.set_status(status) raise else: return result finally: tracer.end_span()
def _stop(self, code, message='', details=None): span = self.tracer.current_span() status = status_module.Status(code=code, message=message, details=details) span.set_status(status) self.tracer.end_span()
def _teardown_request(self, exception): # Do not trace if the url is blacklisted if utils.disable_tracing_url(flask.request.url, self.blacklist_paths): return try: tracer = execution_context.get_opencensus_tracer() if exception is not None: span = execution_context.get_current_span() span.status = status.Status( code=code_pb2.UNKNOWN, message=str(exception) ) # try attaching the stack trace to the span, only populated if # the app has 'PROPAGATE_EXCEPTIONS', 'DEBUG', or 'TESTING' # enabled exc_type, _, exc_traceback = sys.exc_info() if exc_traceback is not None: span.stack_trace = stack_trace.StackTrace.from_traceback( exc_traceback ) tracer.end_span() tracer.finish() except Exception: # pragma: NO COVER log.error('Failed to trace request', exc_info=True)
def test_translate_status(self): span_data = span_data_module.SpanData( context=span_context_module.SpanContext( trace_id='6e0c63257de34c92bf9efcd03927272e'), span_id='6e0c63257de34c92', status=status_module.Status(code=2, message='ERR', details='details'), span_kind=span_module.SpanKind.SERVER, 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, annotations=None, message_events=None, links=None) pb_span = utils.translate_to_trace_proto(span_data) self.assertEqual(pb_span.status.code, 2) self.assertEqual(pb_span.status.message, 'ERR')
def _add_exc_info(span): exc_type, exc_value, tb = sys.exc_info() span.add_attribute( attributes_helper.COMMON_ATTRIBUTES.get(ATTRIBUTE_ERROR_MESSAGE), str(exc_value)) span.stack_trace = stack_trace.StackTrace.from_traceback(tb) span.status = status.Status(code=code_pb2.UNKNOWN, message=str(exc_value))
def test_format_status_json_without_message(self): code = 100 status = status_module.Status(code=code) status_json = status.format_status_json() expected_status_json = {'code': code} self.assertEqual(expected_status_json, status_json)
def test_constructor(self): code = 100 message = 'test message' status = status_module.Status(code=code, message=message) self.assertEqual(status.canonical_code, code) self.assertEqual(status.description, message) self.assertIsNone(status.details)
def test_format_status_json_without_details(self): code = 100 message = 'test message' status = status_module.Status(code=code, message=message) status_json = status.format_status_json() expected_status_json = {'code': code, 'message': message} self.assertEqual(expected_status_json, status_json)
def _end_server_span(self, rpc_response_info): tracer = execution_context.get_opencensus_tracer() exc_type, exc_value, tb = rpc_response_info.exc_info if exc_type is not None: current_span = tracer.current_span() current_span.add_attribute( attributes_helper.COMMON_ATTRIBUTES.get( ATTRIBUTE_ERROR_MESSAGE), str(exc_value)) current_span.stack_trace = stack_trace.StackTrace.from_traceback( tb) current_span.status = status.Status(code=code_pb2.UNKNOWN, message=str(exc_value)) tracer.end_span()
def __enter__(self): tracer = self._get_current_tracer if not tracer: return self span = tracer.start_span() span.name = 'memcached.op' span.span_kind = span_module.SpanKind.CLIENT span.set_status(status_module.Status(code_pb2.UNKNOWN)) tracer.add_attribute_to_current_span('component', 'memcached') tracer.add_attribute_to_current_span('python.traceback', common_utils.get_traceback()) return self
def test_wrap_requests_exception(self): mock_return = mock.Mock() mock_return.status_code = 200 return_value = mock_return mock_func = mock.Mock() mock_func.__name__ = 'get' mock_func.return_value = return_value mock_func.side_effect = requests.TooManyRedirects mock_tracer = MockTracer() patch = mock.patch( 'opencensus.ext.requests.trace.execution_context.' 'get_opencensus_tracer', return_value=mock_tracer) patch_thread = mock.patch( 'opencensus.ext.requests.trace.execution_context.' 'is_exporter', return_value=False) wrapped = trace.wrap_requests(mock_func) url = 'http://localhost:8080/test' with patch, patch_thread: with self.assertRaises(requests.TooManyRedirects): wrapped(url) expected_attributes = { 'component': 'HTTP', 'http.host': 'localhost:8080', 'http.method': 'GET', 'http.path': '/test', 'http.url': url, } expected_name = '/test' expected_status = status_module.Status(2, '') self.assertEqual(span_module.SpanKind.CLIENT, mock_tracer.current_span.span_kind) self.assertEqual(expected_attributes, mock_tracer.current_span.attributes) self.assertEqual(expected_name, mock_tracer.current_span.name) self.assertEqual(expected_status.__dict__, mock_tracer.current_span.status.__dict__) self.assertRaises(requests.TooManyRedirects, mock_func)
def test_wrap_session_request_exception(self): wrapped = mock.Mock(return_value=mock.Mock(status_code=200)) wrapped.side_effect = requests.TooManyRedirects mock_tracer = MockTracer( propagator=mock.Mock( to_headers=lambda x: {'x-trace': 'some-value'})) patch = mock.patch( 'opencensus.ext.requests.trace.execution_context.' 'get_opencensus_tracer', return_value=mock_tracer) patch_thread = mock.patch( 'opencensus.ext.requests.trace.execution_context.' 'is_exporter', return_value=False) url = 'http://localhost:8080/test' request_method = 'POST' kwargs = {} with patch, patch_thread: trace.wrap_session_request(wrapped, 'Session.request', (request_method, url), kwargs) expected_attributes = { 'http.host': 'localhost:8080', 'http.method': 'POST', 'http.path': '/test', 'http.url': url, } expected_name = '/test' expected_status = status_module.Status(2, '') self.assertEqual(span_module.SpanKind.CLIENT, mock_tracer.current_span.span_kind) self.assertEqual(expected_attributes, mock_tracer.current_span.attributes) self.assertEqual(kwargs['headers']['x-trace'], 'some-value') self.assertEqual(expected_name, mock_tracer.current_span.name) self.assertEqual( expected_status.__dict__, mock_tracer.current_span.status.__dict__ )
def test_format_status_json_with_details(self): code = 100 message = 'test message' details = [ { '@type': 'string', 'field1': 'value', }, ] status = status_module.Status( code=code, message=message, details=details) status_json = status.format_status_json() expected_status_json = { 'code': code, 'message': message, 'details': details } self.assertEqual(expected_status_json, status_json)
def test_is_ok(self): status = status_module.Status.as_ok() self.assertTrue(status.is_ok) status = status_module.Status(code=code_pb2.UNKNOWN) self.assertFalse(status.is_ok)
def setstatus(self, status): tracer = self._get_current_tracer if not tracer: return tracer.current_span().set_status(status_module.Status(status))
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])