def test_get_and_set_full_context(self): mock_tracer_get = mock.Mock() mock_span_get = mock.Mock() execution_context.set_opencensus_tracer(mock_tracer_get) execution_context.set_current_span(mock_span_get) execution_context.set_opencensus_attr("test", "test_value") tracer, span, attrs = execution_context.get_opencensus_full_context() self.assertEqual(mock_tracer_get, tracer) self.assertEqual(mock_span_get, span) self.assertEqual({"test": "test_value"}, attrs) mock_tracer_set = mock.Mock() mock_span_set = mock.Mock() execution_context.set_opencensus_full_context(mock_tracer_set, mock_span_set, None) self.assertEqual(mock_tracer_set, execution_context.get_opencensus_tracer()) self.assertEqual(mock_span_set, execution_context.get_current_span()) self.assertEqual({}, execution_context.get_opencensus_attrs()) execution_context.set_opencensus_full_context( mock_tracer_set, mock_span_set, {"test": "test_value"}) self.assertEqual("test_value", execution_context.get_opencensus_attr("test"))
def wrap_poller_start(wrapped, instance, args, kwargs): # Pick up the tracer associated with the poller (if any) and associate it with the current context tracer = getattr(instance, '_opencensus_tracer', None) execution_context.set_opencensus_tracer(tracer) with tracer.span('[msrest]polling'): result = wrapped(*args, **kwargs) return result
def _start_client_span(self, client_call_details): span = self.tracer.start_span(name=_get_span_name(client_call_details)) span.span_kind = span_module.SpanKind.CLIENT # Add the component grpc to span attribute self.tracer.add_attribute_to_current_span( attribute_key=attributes_helper.COMMON_ATTRIBUTES.get( ATTRIBUTE_COMPONENT), attribute_value='grpc') # Add the host:port info to span attribute self.tracer.add_attribute_to_current_span( attribute_key=attributes_helper.GRPC_ATTRIBUTES.get( GRPC_HOST_PORT), attribute_value=self.host_port) # Add the method to span attribute self.tracer.add_attribute_to_current_span( attribute_key=attributes_helper.GRPC_ATTRIBUTES.get(GRPC_METHOD), attribute_value=str(client_call_details.method)) execution_context.set_opencensus_tracer(self.tracer) execution_context.set_current_span(span) return span
def _start_server_span(self, servicer_context): metadata = servicer_context.invocation_metadata() span_context = None if metadata is not None: propagator = binary_format.BinaryFormatPropagator() metadata_dict = dict(metadata) trace_header = metadata_dict.get(oc_grpc.GRPC_TRACE_KEY) span_context = propagator.from_header(trace_header) tracer = tracer_module.Tracer(span_context=span_context, sampler=self.sampler, exporter=self.exporter) span = tracer.start_span(name=_get_span_name(servicer_context)) span.span_kind = span_module.SpanKind.SERVER tracer.add_attribute_to_current_span( attribute_key=attributes_helper.COMMON_ATTRIBUTES.get( ATTRIBUTE_COMPONENT), attribute_value='grpc') execution_context.set_opencensus_tracer(tracer) execution_context.set_current_span(span) return span
def trace_integration(tracer=None): log.info('Integrated module: {}'.format(MODULE_NAME)) if tracer is not None: # The execution_context tracer should never be None - if it has not # been set it returns a no-op tracer. Most code in this library does # not handle None being used in the execution context. execution_context.set_opencensus_tracer(tracer) trace_tornado_httpclient()
def trace_integration(tracer=None): """Wrap the msrest library to trace it.""" log.info('Integrated module: {}'.format(MODULE_NAME)) execution_context.set_opencensus_tracer(tracer) for name in SERVICECLIENT_WRAP_METHODS: # Wrap msrest.ServiceClient class wrapt.wrap_function_wrapper( MODULE_NAME, 'common.storageclient.StorageClient.{}'.format(name), wrap_serviceclient_request)
def test_intercept_unary_stream_trace(self): interceptor, continuation, mock_tracer = self._stream_helper() execution_context.set_opencensus_tracer(mock_tracer) client_call_details = mock.Mock() client_call_details.method = 'test' response_iter = interceptor.intercept_unary_stream( continuation, client_call_details, []) for _ in response_iter: pass self.assertTrue(mock_tracer.end_span.called)
def setUp(self): super(TestClient, self).setUp() self.exporter = CapturingExporter() self.tracer = tracer_module.Tracer( sampler=AlwaysOnSampler(), exporter=self.exporter, propagator=GoogleCloudFormatPropagator()) self.stack_context = tracer_stack_context() self.stack_context.__enter__() execution_context.set_opencensus_tracer(self.tracer)
def __call__(self, *args, **kwargs): kwds = kwargs.pop("kwds") span_context_binary = kwargs.pop("span_context_binary") propagator = binary_format.BinaryFormatPropagator() kwargs["span_context"] = propagator.from_header(span_context_binary) _tracer = NoopTracer() if kwargs.get("noop", False) else tracer.Tracer(**kwargs) execution_context.set_opencensus_tracer(_tracer) result = self.func(*args, **kwds) return result
def __call__(self, *args, **kwargs): kwds = kwargs.pop("kwds") span_context_binary = kwargs.pop("span_context_binary") propagator = binary_format.BinaryFormatPropagator() kwargs["span_context"] = propagator.from_header(span_context_binary) _tracer = tracer.Tracer(**kwargs) execution_context.set_opencensus_tracer(_tracer) with _tracer.span(name=threading.current_thread().name): result = self.func(*args, **kwds) execution_context.clean() return result
def test_wrap_pool(self): _tracer = tracer.Tracer() execution_context.set_opencensus_tracer(tracer) trace.trace_integration() context = tracer.Tracer().span_context print(context.trace_id) pool = Pool(processes=1) with _tracer.span(name='span1'): result = pool.apply_async(fake_pooled_func, ()).get(timeout=1) self.assertEqual(result, context.trace_id)
def test_wrap_futures(self): _tracer = tracer.Tracer() execution_context.set_opencensus_tracer(tracer) trace.trace_integration() context = tracer.Tracer().span_context print(context.trace_id) pool = ThreadPoolExecutor(max_workers=1) with _tracer.span(name='span1'): future = pool.submit(fake_pooled_func) result = future.result() self.assertEqual(result, context.trace_id)
def prerun_task_span(task_id=None, task=None, *args, **kwargs): if settings.STACKDRIVER_TRACE_PROJECT_ID: exporter = stackdriver_exporter.StackdriverExporter( project_id=settings.STACKDRIVER_TRACE_PROJECT_ID, transport=BackgroundThreadTransport) sampler = probability.ProbabilitySampler( rate=settings.CELERY_TRACE_SAMPLING_RATE) tracer = tracer_module.Tracer(exporter=exporter, sampler=sampler) span = tracer.start_span() span.name = '[celery]{0}'.format(task.name) execution_context.set_opencensus_tracer(tracer) span.add_attribute('args', str(kwargs['args'])) span.add_attribute('kwargs', str(kwargs['kwargs'])) execution_context.set_current_span(span)
def test_wrap_threading(self): global global_tracer mock_span = mock.Mock() span_id = '1234' mock_span.span_id = span_id mock_tracer = MockTracer(mock_span) execution_context.set_opencensus_tracer(mock_tracer) trace.trace_integration() t = threading.Thread(target=self.fake_threaded_func) t.start() t.join() assert isinstance(global_tracer, MockTracer)
def test_clean_tracer(self): mock_tracer = mock.Mock() some_value = mock.Mock() execution_context.set_opencensus_tracer(mock_tracer) thread_local = threading.local() setattr(thread_local, 'random_non_oc_attr', some_value) execution_context.clean() self.assertNotEqual(mock_tracer, execution_context.get_opencensus_tracer()) self.assertEqual(some_value, getattr(thread_local, 'random_non_oc_attr'))
def trace_integration(tracer=None): """Wrap the requests library to trace it.""" log.info('Integrated module: {}'.format(MODULE_NAME)) execution_context.set_opencensus_tracer(tracer) # Wrap the requests functions for func in REQUESTS_WRAP_METHODS: requests_func = getattr(requests, func) wrapped = wrap_requests(requests_func) setattr(requests, requests_func.__name__, wrapped) # Wrap Session class wrapt.wrap_function_wrapper(MODULE_NAME, 'Session.request', wrap_session_request)
def set_current_tracer(cls, tracer): # type: (Tracer) -> None """ Set the given tracer as the current tracer in the execution context. :param tracer: The tracer to set the current tracer as :type tracer: :class: opencensus.trace.Tracer """ return execution_context.set_opencensus_tracer(tracer)
def trace_integration(tracer = None): """Wrap the msrest library to trace it.""" log.info('Integrated module: {}'.format(MODULE_NAME)) execution_context.set_opencensus_tracer(tracer) for name in SERVICECLIENT_WRAP_METHODS: # Wrap msrest.ServiceClient class wrapt.wrap_function_wrapper( MODULE_NAME, 'ServiceClient.{}'.format(name), wrap_serviceclient_request) for name in PAGED_WRAP_METHODS: # Wrap msrest.Pagedclass wrapt.wrap_function_wrapper( MODULE_NAME + '.paging', 'Paged.{}'.format(name), wrap_paged_request) wrapt.wrap_function_wrapper('msrest', 'polling.LROPoller.__init__', wrap_poller_init) wrapt.wrap_function_wrapper('msrest', 'polling.LROPoller._start', wrap_poller_start)
def trace_integration(tracer=None): """Wrap the requests library to trace it.""" log.info('Integrated module: {}'.format(MODULE_NAME)) if tracer is not None: # The execution_context tracer should never be None - if it has not # been set it returns a no-op tracer. Most code in this library does # not handle None being used in the execution context. execution_context.set_opencensus_tracer(tracer) # Wrap Session class # Since # https://github.com/psf/requests/commit/d72d1162142d1bf8b1b5711c664fbbd674f349d1 # (v0.7.0, Oct 23, 2011), get, post, etc are implemented via request which # again, is implemented via Session.request (`Session` was named `session` # before v1.0.0, Dec 17, 2012, see # https://github.com/psf/requests/commit/4e5c4a6ab7bb0195dececdd19bb8505b872fe120) wrapt.wrap_function_wrapper(MODULE_NAME, 'Session.request', wrap_session_request)
def trace_integration(tracer=None): """Wrap the requests library to trace it.""" log.info('Integrated module: {}'.format(MODULE_NAME)) if tracer is not None: # The execution_context tracer should never be None - if it has not # been set it returns a no-op tracer. Most code in this library does # not handle None being used in the execution context. execution_context.set_opencensus_tracer(tracer) # Wrap the requests functions for func in REQUESTS_WRAP_METHODS: requests_func = getattr(requests, func) wrapped = wrap_requests(requests_func) setattr(requests, requests_func.__name__, wrapped) # Wrap Session class wrapt.wrap_function_wrapper(MODULE_NAME, 'Session.request', wrap_session_request)
def initialize( self, schema=None, middleware: Optional[Any] = None, root_value: Any = None, graphiql: bool = False, pretty: bool = False, batch: bool = False, extensions: List[Union[Callable[[], GraphQLExtension], GraphQLExtension]] = None, exporter=None, ): super().initialize(schema, middleware, root_value, graphiql, pretty, batch, extensions) execution_context.set_opencensus_tracer( tracer_module.Tracer( sampler=AlwaysOnSampler(), exporter=exporter, propagator=GoogleCloudFormatPropagator(), ))
def test_decorator_correctly_wrap_and_trace_func(self): """Test that we wrap correctly the function and that a span is created.""" test_tracer = tracer.Tracer() def test_traced_func(self): _tracer = execution_context.get_opencensus_tracer() _span = _tracer.current_span() return _span.name execution_context.set_opencensus_tracer(test_tracer) wrapped = tracing.trace(test_traced_func) mock_self = mock.Mock() mock_self.module_name = "module_name" span_name = wrapped(mock_self) expected_name = "module_name.test_traced_func" self.assertEqual(expected_name, span_name)
def test_ensure_exceptions_are_raised_yet_reported(): span_retainer = RetainerTraceExporter() tracer = Tracer(sampler=AlwaysOnSampler(), exporter=span_retainer) execution_context.set_opencensus_tracer(tracer) view_data_retainer = RetainerStatsExporter() view_manager = stats.stats.view_manager view_manager.register_exporter(view_data_retainer) ocredis.register_views() with pytest.raises(Exception): invalid_port = 1<<18 client = ocredis.OcRedis(host='localhost', port=invalid_port) client.get('newer') spans = span_retainer.spans() assert len(spans) == 1 span0 = spans[0] assert span0.name == 'redispy.Redis.get' # Ensure that the span for .get is the root span. assert span0.parent_span_id == None # Now check that the top most span has a Status root_span_status = span0.status assert root_span_status.code == 2 # Unknown as per https://opencensus.io/tracing/span/status/#status-code-mapping assert root_span_status.message == 'Error 8 connecting to localhost:262144. nodename nor servname provided, or not known.' assert root_span_status.details == None # Next let's check that stats are recorded. view_data_list = view_data_retainer.view_data() assert len(view_data_list) >= 2 # Expecting the values for the various views per method. # However, since stats recording is time-imprecise we can # less or more values recorded, hence bucketize view_data by # name first and then perform the various assertions. view_data_by_name = bucketize_view_data_by_name(view_data_list) calls_view_data_list = view_data_by_name['redispy/calls'] assert len(calls_view_data_list) > 0 latency_view_data_list = view_data_by_name['redispy/latency'] assert len(latency_view_data_list) > 0 calls_view_data_get = calls_view_data_list[0] latency_view_data_execute_command = latency_view_data_list[0] count_aggregation = CountAggregation() view_calls_execute_command = calls_view_data_get.view # assert view_calls_execute_command.aggregation.count == 1 assert view_calls_execute_command.name == "redispy/calls" assert view_calls_execute_command.description == "The number of calls" assert view_calls_execute_command.columns == ['method', 'error', 'status'] # calls_execute_command_tag_values = view_calls_execute_command.get_tag_values( # calls_view_data_get.columns, view_calls_execute_command.columns) calls_tag_values = calls_view_data_get.tag_value_aggregation_data_map.keys() sorted_calls_tag_values = sorted(calls_tag_values, key=lambda tag_value_tuple: tag_value_tuple[0]) print(sorted_calls_tag_values) assert len(sorted_calls_tag_values) >= 1 assert sorted_calls_tag_values[0] == ( 'redispy.Redis.get', 'Error 8 connecting to localhost:262144. nodename nor servname provided, or not known.', 'ERROR', ) latency_distribution_aggregation = DistributionAggregation() view_latency_execute_command = latency_view_data_execute_command.view # assert view_calls_execute_command.aggregation.count == 1 assert view_latency_execute_command.name == "redispy/latency" assert view_latency_execute_command.description == "The distribution of the latencies per method" assert view_latency_execute_command.columns == ['method', 'error', 'status'] # calls_execute_command_tag_values = view_calls_execute_command.get_tag_values( # calls_view_data_get.columns, view_calls_execute_command.columns) # TODO: File a bug with OpenCensus-Python about them using strings # for start and endtime, instead of actual date* objects on which we # can easily calculate time spent etc. assert latency_view_data_execute_command.start_time != '' assert latency_view_data_execute_command.end_time != ''
def store_tracer(self): """Add the current tracer to thread_local""" execution_context.set_opencensus_tracer(self)
def __init__(self, *args, **kwargs): self._current_span = span_module.Span('mock_span') execution_context.set_opencensus_tracer(self)
def __init__(self, *args, **kwargs): self.current_span = mock.Mock() self.current_span.attributes = {} execution_context.set_opencensus_tracer(self)