def test_intercept_service(self): test_dimensions = [ ['unary_unary', False, False], ['unary_stream', False, True], ['stream_unary', True, False], ['stream_stream', True, True], ] for rpc_fn_name, req_streaming, rsp_streaming in test_dimensions: patch = mock.patch( 'opencensus.ext.grpc.server_interceptor.tracer_module' '.Tracer', MockTracer) mock_context = mock.Mock() mock_context.invocation_metadata = mock.Mock( return_value=(('test_key', b'test_value'), )) mock_handler = mock.Mock() mock_handler.request_streaming = req_streaming mock_handler.response_streaming = rsp_streaming mock_continuation = mock.Mock(return_value=mock_handler) mock_context._rpc_event.call_details.method = 'hello' interceptor = server_interceptor.OpenCensusServerInterceptor( None, None) with patch: handler = interceptor.intercept_service( mock_continuation, mock.Mock()) getattr(handler, rpc_fn_name)(mock.Mock(), mock_context) expected_attributes = { 'component': 'grpc', } self.assertEqual( execution_context.get_opencensus_tracer().current_span(). attributes, expected_attributes)
def test_intercept_service_no_metadata(self): patch = mock.patch( 'opencensus.ext.grpc.server_interceptor' '.tracer_module.Tracer', MockTracer) mock_context = mock.Mock() mock_context.invocation_metadata = mock.Mock(return_value=None) mock_context._rpc_event.call_details.method = 'hello' interceptor = server_interceptor.OpenCensusServerInterceptor( None, None) mock_handler = mock.Mock() mock_handler.request_streaming = False mock_handler.response_streaming = False mock_continuation = mock.Mock(return_value=mock_handler) with patch: interceptor.intercept_service(mock_continuation, mock.Mock()).unary_unary( mock.Mock(), mock_context) expected_attributes = { 'component': 'grpc', } self.assertEqual( execution_context.get_opencensus_tracer().current_span(). attributes, expected_attributes)
def test_constructor(self): sampler = mock.Mock() exporter = mock.Mock() interceptor = server_interceptor.OpenCensusServerInterceptor( sampler=sampler, exporter=exporter) self.assertEqual(interceptor.sampler, sampler) self.assertEqual(interceptor.exporter, exporter)
def test_intercept_handler_exception(self): test_dimensions = [ ['unary_unary', False, False], ['unary_stream', False, True], ['stream_unary', True, False], ['stream_stream', True, True], ] for rpc_fn_name, req_streaming, rsp_streaming in test_dimensions: patch = mock.patch( 'opencensus.ext.grpc.server_interceptor' '.tracer_module.Tracer', MockTracer) interceptor = server_interceptor.OpenCensusServerInterceptor( None, None) mock_context = mock.Mock() mock_context.invocation_metadata = mock.Mock(return_value=None) mock_context._rpc_event.call_details.method = 'hello' mock_handler = mock.Mock() mock_handler.request_streaming = req_streaming mock_handler.response_streaming = rsp_streaming setattr(mock_handler, rpc_fn_name, mock.Mock(side_effect=Exception('Test'))) mock_continuation = mock.Mock(return_value=mock_handler) # mock_continuation.unary_unary = mock.Mock()) with patch: # patch the wrapper's handler to return an exception handler = interceptor.intercept_service( mock_continuation, mock.Mock()) with self.assertRaises(Exception): getattr(handler, rpc_fn_name)(mock.Mock(), mock_context) expected_attributes = { 'component': 'grpc', 'error.message': 'Test' } current_span = execution_context.get_opencensus_tracer( ).current_span() self.assertEqual( execution_context.get_opencensus_tracer().current_span(). attributes, expected_attributes) self.assertEqual(current_span.span_kind, span_module.SpanKind.SERVER) # check that the stack trace is attached to the current span self.assertIsNotNone(current_span.stack_trace) self.assertIsNotNone(current_span.stack_trace.stack_trace_hash_id) self.assertNotEqual(current_span.stack_trace.stack_frames, []) # check that the status obj is attached to the current span self.assertIsNotNone(current_span.status) self.assertEqual( current_span.status.canonical_code, code_pb2.UNKNOWN ) self.assertEqual(current_span.status.description, 'Test')
def serve(): sampler = always_on.AlwaysOnSampler() exporter = stackdriver_exporter.StackdriverExporter() tracer_interceptor = server_interceptor.OpenCensusServerInterceptor( sampler, exporter) server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=(tracer_interceptor, )) hello_world_pb2_grpc.add_GreeterServicer_to_server(HelloWorld(), server) server.add_insecure_port('[::]:50051') server.start() try: while True: time.sleep(_ONE_DAY_IN_SECONDS) except KeyboardInterrupt: server.stop(0)
else: logger.info("Profiler enabled.") initStackdriverProfiling() except KeyError: logger.info("Profiler disabled.") try: if "DISABLE_TRACING" in os.environ: raise KeyError() else: logger.info("Tracing enabled.") sampler = samplers.AlwaysOnSampler() exporter = stackdriver_exporter.StackdriverExporter( project_id=os.environ.get('GCP_PROJECT_ID'), transport=AsyncTransport) tracer_interceptor = server_interceptor.OpenCensusServerInterceptor( sampler, exporter) except (KeyError, DefaultCredentialsError): logger.info("Tracing disabled.") tracer_interceptor = server_interceptor.OpenCensusServerInterceptor() except Exception as e: logger.warn( f"Exception on Cloud Trace setup: {traceback.format_exc()}, tracing disabled." ) tracer_interceptor = server_interceptor.OpenCensusServerInterceptor() try: if "DISABLE_DEBUGGER" in os.environ: raise KeyError() else: logger.info("Debugger enabled.") try:
# Export traces to Google Cloud Trace # When running on GCP, the exporter handles authentication # using automatically default application credentials. # When running locally, credentials may need to be set explicitly. cloud_trace_exporter = CloudTraceSpanExporter( project_id=os.environ.get('PROJECT_ID'), ) trace.get_tracer_provider().add_span_processor( SimpleExportSpanProcessor(cloud_trace_exporter) ) # TODO: remove OpenCensus after conversion to OpenTelemetry try: sampler = samplers.AlwaysOnSampler() exporter = stackdriver_exporter.StackdriverExporter() oc_interceptor = oc_server_interceptor.OpenCensusServerInterceptor(sampler, exporter) except: oc_interceptor = oc_server_interceptor.OpenCensusServerInterceptor() try: googleclouddebugger.enable( module='recommendationserver', version='1.0.0' ) except (Exception, err): logger.error("could not enable debugger") logger.error(traceback.print_exc()) pass port = os.environ.get('PORT', "8080") catalog_addr = os.environ.get('PRODUCT_CATALOG_SERVICE_ADDR', '')
# Setup Zipkin exporter try: zipkin_service_addr = os.environ.get("ZIPKIN_SERVICE_ADDR", '') if zipkin_service_addr == "": logger.info( "Skipping Zipkin traces initialization. Set environment variable ZIPKIN_SERVICE_ADDR=<host>:<port> to enable." ) raise KeyError() host, port = zipkin_service_addr.split(":") ze = ZipkinExporter(service_name="recommendationservice-server", host_name=host, port=int(port), endpoint='/api/v2/spans') sampler = AlwaysOnSampler() tracer = Tracer(exporter=ze, sampler=sampler) tracer_interceptor = server_interceptor.OpenCensusServerInterceptor( sampler, ze) logger.info("Zipkin traces enabled, sending to " + zipkin_service_addr) except KeyError: tracer_interceptor = server_interceptor.OpenCensusServerInterceptor() class RecommendationService(demo_pb2_grpc.RecommendationServiceServicer): def ListRecommendations(self, request, context): max_responses = 5 # fetch list of products from product catalog stub cat_response = product_catalog_stub.ListProducts(demo_pb2.Empty()) product_ids = [x.id for x in cat_response.products] filtered_products = list(set(product_ids) - set(request.product_ids)) num_products = len(filtered_products) num_return = min(max_responses, num_products) # sample list of indicies to return
import time from concurrent import futures from dapr.ext.grpc import App, InvokeMethodRequest, InvokeMethodResponse from opencensus.trace.samplers import AlwaysOnSampler from opencensus.trace.tracer import Tracer from opencensus.ext.grpc import server_interceptor from opencensus.trace.samplers import AlwaysOnSampler tracer_interceptor = server_interceptor.OpenCensusServerInterceptor( AlwaysOnSampler()) app = App(thread_pool=futures.ThreadPoolExecutor(max_workers=10), interceptors=(tracer_interceptor, )) @app.method(name='say') def say(request: InvokeMethodRequest) -> InvokeMethodResponse: tracer = Tracer(sampler=AlwaysOnSampler()) with tracer.span(name='say') as span: data = request.text() span.add_annotation('Request length', len=len(data)) print(request.metadata, flush=True) print(request.text(), flush=True) return InvokeMethodResponse(b'SAY', "text/plain; charset=UTF-8") @app.method(name='sleep') def sleep(request: InvokeMethodRequest) -> InvokeMethodResponse: