def test_span_lifetime(self):
        """Check that the span is active for the duration of the call."""

        interceptor = server_interceptor()

        # To capture the current span at the time the handler is called
        active_span_in_handler = None

        def handler(request, context):
            nonlocal active_span_in_handler
            active_span_in_handler = trace.get_current_span()
            return b""

        server = grpc.server(
            futures.ThreadPoolExecutor(max_workers=1),
            options=(("grpc.so_reuseport", 0), ),
            interceptors=[interceptor],
        )
        server.add_generic_rpc_handlers((UnaryUnaryRpcHandler(handler), ))

        port = server.add_insecure_port("[::]:0")
        channel = grpc.insecure_channel("localhost:{:d}".format(port))

        active_span_before_call = trace.get_current_span()
        try:
            server.start()
            channel.unary_unary("TestServicer/handler")(b"")
        finally:
            server.stop(None)
        active_span_after_call = trace.get_current_span()

        self.assertEqual(active_span_before_call, trace.INVALID_SPAN)
        self.assertEqual(active_span_after_call, trace.INVALID_SPAN)
        self.assertIsInstance(active_span_in_handler, trace_sdk.Span)
        self.assertIsNone(active_span_in_handler.parent)
Esempio n. 2
0
    def test_sequential_server_spans(self):
        """Check that sequential RPCs get separate server spans."""

        interceptor = server_interceptor()

        # Capture the currently active span in each thread
        active_spans_in_handler = []

        def handler(request, context):
            active_spans_in_handler.append(trace.get_current_span())
            return b""

        with futures.ThreadPoolExecutor(max_workers=1) as executor:
            server = grpc.server(
                executor,
                options=(("grpc.so_reuseport", 0), ),
                interceptors=[interceptor],
            )
            server.add_generic_rpc_handlers((UnaryUnaryRpcHandler(handler), ))

            port = server.add_insecure_port("[::]:0")
            channel = grpc.insecure_channel("localhost:{:d}".format(port))

            try:
                server.start()
                channel.unary_unary("TestServicer/handler")(b"")
                channel.unary_unary("TestServicer/handler")(b"")
            finally:
                server.stop(None)

        self.assertEqual(len(active_spans_in_handler), 2)
        # pylint:disable=unbalanced-tuple-unpacking
        span1, span2 = active_spans_in_handler
        # Spans should belong to separate traces
        self.assertNotEqual(span1.context.span_id, span2.context.span_id)
        self.assertNotEqual(span1.context.trace_id, span2.context.trace_id)

        for span in (span1, span2):
            # each should be a root span
            self.assertIsNone(span2.parent)

            # check attributes
            self.assert_span_has_attributes(
                span,
                {
                    SpanAttributes.NET_PEER_IP:
                    "[::1]",
                    SpanAttributes.NET_PEER_NAME:
                    "localhost",
                    SpanAttributes.RPC_METHOD:
                    "handler",
                    SpanAttributes.RPC_SERVICE:
                    "TestServicer",
                    SpanAttributes.RPC_SYSTEM:
                    "grpc",
                    SpanAttributes.RPC_GRPC_STATUS_CODE:
                    grpc.StatusCode.OK.value[0],
                },
            )
Esempio n. 3
0
def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    server = intercept_server(server, server_interceptor())

    route_guide_pb2_grpc.add_RouteGuideServicer_to_server(
        RouteGuideServicer(), server)
    server.add_insecure_port("[::]:50051")
    server.start()
    server.wait_for_termination()
def serve():

    server = grpc.server(futures.ThreadPoolExecutor())
    server = intercept_server(server, server_interceptor())

    helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
    server.add_insecure_port("[::]:50051")
    server.start()
    server.wait_for_termination()
Esempio n. 5
0
def serve():
    trace.set_tracer_provider(TracerProvider())
    trace.get_tracer_provider().add_span_processor(
        SimpleExportSpanProcessor(ConsoleSpanExporter()))

    propagators.set_global_textmap(B3Format())

    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10),
                         interceptors=[server_interceptor()])
    add_ImageServiceServicer_to_server(ImageServer(), server)
    server.add_insecure_port("[::]:50051")
    server.start()
    server.wait_for_termination()
    def test_create_span(self):
        """Check that the interceptor wraps calls with spans server-side."""

        # Intercept gRPC calls...
        interceptor = server_interceptor()

        # No-op RPC handler
        def handler(request, context):
            return b""

        server = grpc.server(
            futures.ThreadPoolExecutor(max_workers=1),
            options=(("grpc.so_reuseport", 0), ),
            interceptors=[interceptor],
        )

        server.add_generic_rpc_handlers((UnaryUnaryRpcHandler(handler), ))

        port = server.add_insecure_port("[::]:0")
        channel = grpc.insecure_channel("localhost:{:d}".format(port))

        rpc_call = "TestServicer/handler"
        try:
            server.start()
            channel.unary_unary(rpc_call)(b"")
        finally:
            server.stop(None)

        spans_list = self.memory_exporter.get_finished_spans()
        self.assertEqual(len(spans_list), 1)
        span = spans_list[0]

        self.assertEqual(span.name, rpc_call)
        self.assertIs(span.kind, trace.SpanKind.SERVER)

        # Check version and name in span's instrumentation info
        self.check_span_instrumentation_info(
            span, opentelemetry.instrumentation.grpc)

        # Check attributes
        self.assert_span_has_attributes(
            span,
            {
                "net.peer.ip": "[::1]",
                "net.peer.name": "localhost",
                "rpc.method": "handler",
                "rpc.service": "TestServicer",
                "rpc.system": "grpc",
                "rpc.grpc.status_code": grpc.StatusCode.OK.value[0],
            },
        )
    def test_create_span_streaming(self):
        """Check that the interceptor wraps calls with spans server-side, on a
        streaming call."""

        # Intercept gRPC calls...
        interceptor = server_interceptor()

        # setup the server
        server = grpc.server(
            futures.ThreadPoolExecutor(max_workers=1),
            options=(("grpc.so_reuseport", 0), ),
            interceptors=[interceptor],
        )
        add_GRPCTestServerServicer_to_server(Servicer(), server)
        port = server.add_insecure_port("[::]:0")
        channel = grpc.insecure_channel("localhost:{:d}".format(port))

        # setup the RPC
        rpc_call = "/GRPCTestServer/ServerStreamingMethod"
        request = Request(client_id=1, request_data="test")
        msg = request.SerializeToString()
        try:
            server.start()
            list(channel.unary_stream(rpc_call)(msg))
        finally:
            server.stop(None)

        spans_list = self.memory_exporter.get_finished_spans()
        self.assertEqual(len(spans_list), 1)
        span = spans_list[0]

        self.assertEqual(span.name, rpc_call)
        self.assertIs(span.kind, trace.SpanKind.SERVER)

        # Check version and name in span's instrumentation info
        self.check_span_instrumentation_info(
            span, opentelemetry.instrumentation.grpc)

        # Check attributes
        self.assert_span_has_attributes(
            span,
            {
                SpanAttributes.NET_PEER_IP: "[::1]",
                SpanAttributes.NET_PEER_NAME: "localhost",
                SpanAttributes.RPC_METHOD: "ServerStreamingMethod",
                SpanAttributes.RPC_SERVICE: "GRPCTestServer",
                SpanAttributes.RPC_SYSTEM: "grpc",
                SpanAttributes.RPC_GRPC_STATUS_CODE:
                grpc.StatusCode.OK.value[0],
            },
        )
    def test_concurrent_server_spans(self):
        """Check that concurrent RPC calls don't interfere with each other.

        This is the same check as test_sequential_server_spans except that the
        RPCs are concurrent. Two handlers are invoked at the same time on two
        separate threads. Each one should see a different active span and
        context.
        """

        interceptor = server_interceptor()

        # Capture the currently active span in each thread
        active_spans_in_handler = []
        latch = get_latch(2)

        def handler(request, context):
            latch()
            active_spans_in_handler.append(trace.get_current_span())
            return b""

        server = grpc.server(
            futures.ThreadPoolExecutor(max_workers=2),
            options=(("grpc.so_reuseport", 0), ),
            interceptors=[interceptor],
        )
        server.add_generic_rpc_handlers((UnaryUnaryRpcHandler(handler), ))

        port = server.add_insecure_port("[::]:0")
        channel = grpc.insecure_channel("localhost:{:d}".format(port))

        try:
            server.start()
            # Interleave calls so spans are active on each thread at the same
            # time
            with futures.ThreadPoolExecutor(max_workers=2) as tpe:
                f1 = tpe.submit(channel.unary_unary(""), b"")
                f2 = tpe.submit(channel.unary_unary(""), b"")
            futures.wait((f1, f2))
        finally:
            server.stop(None)

        self.assertEqual(len(active_spans_in_handler), 2)
        # pylint:disable=unbalanced-tuple-unpacking
        span1, span2 = active_spans_in_handler
        # Spans should belong to separate traces, and each should be a root
        # span
        self.assertNotEqual(span1.context.span_id, span2.context.span_id)
        self.assertNotEqual(span1.context.trace_id, span2.context.trace_id)
        self.assertIsNone(span1.parent)
        self.assertIsNone(span1.parent)
Esempio n. 9
0
    def __init__(self, name='otel-grpc-test', listen='localhost:50051'):
        self._name = name

        interceptors = []

        self._enable_otel()

        interceptors.append(server_interceptor(self.tracer))

        # here's the gRPC server
        self.server = grpc.server(
            futures.ThreadPoolExecutor(max_workers = 10),
            interceptors = interceptors)

        self.server.add_insecure_port(listen)
        log.info("Listening on %s", listen)
Esempio n. 10
0
    def test_create_span(self):
        """Check that the interceptor wraps calls with spans server-side."""

        # Intercept gRPC calls...
        interceptor = server_interceptor()

        server = grpc.server(
            futures.ThreadPoolExecutor(max_workers=1),
            options=(("grpc.so_reuseport", 0), ),
            interceptors=[interceptor],
        )
        add_GRPCTestServerServicer_to_server(Servicer(), server)
        port = server.add_insecure_port("[::]:0")
        channel = grpc.insecure_channel("localhost:{:d}".format(port))

        rpc_call = "/GRPCTestServer/SimpleMethod"
        request = Request(client_id=1, request_data="test")
        msg = request.SerializeToString()
        try:
            server.start()
            channel.unary_unary(rpc_call)(msg)
        finally:
            server.stop(None)

        spans_list = self.memory_exporter.get_finished_spans()
        self.assertEqual(len(spans_list), 1)
        span = spans_list[0]

        self.assertEqual(span.name, rpc_call)
        self.assertIs(span.kind, trace.SpanKind.SERVER)

        # Check version and name in span's instrumentation info
        self.check_span_instrumentation_info(
            span, opentelemetry.instrumentation.grpc)

        # Check attributes
        self.assert_span_has_attributes(
            span,
            {
                "net.peer.ip": "[::1]",
                "net.peer.name": "localhost",
                "rpc.method": "SimpleMethod",
                "rpc.service": "GRPCTestServer",
                "rpc.system": "grpc",
                "rpc.grpc.status_code": grpc.StatusCode.OK.value[0],
            },
        )
def serve():
    trace.set_tracer_provider(TracerProvider())
    trace.get_tracer_provider().add_span_processor(
        SimpleExportSpanProcessor(ConsoleSpanExporter())
    )
    propagators.set_global_textmap(B3Format())

    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=[server_interceptor()])
    add_ProductInfoServicer_to_server(ProductInfoServer(), server)
    server.add_insecure_port("[::]:50050")
    server.start()
    proxy = MyProxy(ProductInfoServer)
    try:
        proxy.start()
        server.wait_for_termination()
    except KeyboardInterrupt:
        print("terminating")
        proxy.stop()
    print("Goodbye")
    def test_sequential_server_spans(self):
        """Check that sequential RPCs get separate server spans."""

        interceptor = server_interceptor()

        # Capture the currently active span in each thread
        active_spans_in_handler = []

        def handler(request, context):
            active_spans_in_handler.append(trace.get_current_span())
            return b""

        server = grpc.server(
            futures.ThreadPoolExecutor(max_workers=1),
            options=(("grpc.so_reuseport", 0), ),
            interceptors=[interceptor],
        )
        server.add_generic_rpc_handlers((UnaryUnaryRpcHandler(handler), ))

        port = server.add_insecure_port("[::]:0")
        channel = grpc.insecure_channel("localhost:{:d}".format(port))

        try:
            server.start()
            channel.unary_unary("")(b"")
            channel.unary_unary("")(b"")
        finally:
            server.stop(None)

        self.assertEqual(len(active_spans_in_handler), 2)
        # pylint:disable=unbalanced-tuple-unpacking
        span1, span2 = active_spans_in_handler
        # Spans should belong to separate traces, and each should be a root
        # span
        self.assertNotEqual(span1.context.span_id, span2.context.span_id)
        self.assertNotEqual(span1.context.trace_id, span2.context.trace_id)
        self.assertIsNone(span1.parent)
        self.assertIsNone(span1.parent)
    def test_create_span(self):
        """Check that the interceptor wraps calls with spans server-side."""

        # Intercept gRPC calls...
        interceptor = server_interceptor()

        # No-op RPC handler
        def handler(request, context):
            return b""

        server = grpc.server(
            futures.ThreadPoolExecutor(max_workers=1),
            options=(("grpc.so_reuseport", 0), ),
        )
        # FIXME: grpcext interceptor doesn't apply to handlers passed to server
        # init, should use intercept_service API instead.
        server = intercept_server(server, interceptor)
        server.add_generic_rpc_handlers((UnaryUnaryRpcHandler(handler), ))

        port = server.add_insecure_port("[::]:0")
        channel = grpc.insecure_channel("localhost:{:d}".format(port))

        try:
            server.start()
            channel.unary_unary("")(b"")
        finally:
            server.stop(None)

        spans_list = self.memory_exporter.get_finished_spans()
        self.assertEqual(len(spans_list), 1)
        span = spans_list[0]

        self.assertEqual(span.name, "")
        self.assertIs(span.kind, trace.SpanKind.SERVER)

        # Check version and name in span's instrumentation info
        self.check_span_instrumentation_info(
            span, opentelemetry.instrumentation.grpc)
Esempio n. 14
0
def start(dummy_mode):
    # Create gRPC server channel to receive requests from checkout (client).
    interceptor = server_interceptor(trace.get_tracer_provider())
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10),
                         interceptors=(interceptor, ))

    service = None
    if dummy_mode:
        service = DummyEmailService()
    else:
        raise Exception("non-dummy mode not implemented yet")

    demo_pb2_grpc.add_EmailServiceServicer_to_server(service, server)
    health_pb2_grpc.add_HealthServicer_to_server(service, server)

    port = os.environ.get("PORT", "8080")
    logger.info("listening on port: " + port)
    server.add_insecure_port("[::]:" + port)
    server.start()
    try:
        while True:
            time.sleep(3600)
    except KeyboardInterrupt:
        server.stop(0)
Esempio n. 15
0
    def test_concurrent_server_spans(self):
        """Check that concurrent RPC calls don't interfere with each other.

        This is the same check as test_sequential_server_spans except that the
        RPCs are concurrent. Two handlers are invoked at the same time on two
        separate threads. Each one should see a different active span and
        context.
        """

        interceptor = server_interceptor()

        # Capture the currently active span in each thread
        active_spans_in_handler = []
        latch = get_latch(2)

        def handler(request, context):
            latch()
            active_spans_in_handler.append(trace.get_current_span())
            return b""

        with futures.ThreadPoolExecutor(max_workers=2) as executor:
            server = grpc.server(
                executor,
                options=(("grpc.so_reuseport", 0), ),
                interceptors=[interceptor],
            )
            server.add_generic_rpc_handlers((UnaryUnaryRpcHandler(handler), ))

            port = server.add_insecure_port("[::]:0")
            channel = grpc.insecure_channel("localhost:{:d}".format(port))

            try:
                server.start()
                # Interleave calls so spans are active on each thread at the same
                # time
                with futures.ThreadPoolExecutor(max_workers=2) as tpe:
                    f1 = tpe.submit(
                        channel.unary_unary("TestServicer/handler"), b"")
                    f2 = tpe.submit(
                        channel.unary_unary("TestServicer/handler"), b"")
                futures.wait((f1, f2))
            finally:
                server.stop(None)

        self.assertEqual(len(active_spans_in_handler), 2)
        # pylint:disable=unbalanced-tuple-unpacking
        span1, span2 = active_spans_in_handler
        # Spans should belong to separate traces
        self.assertNotEqual(span1.context.span_id, span2.context.span_id)
        self.assertNotEqual(span1.context.trace_id, span2.context.trace_id)

        for span in (span1, span2):
            # each should be a root span
            self.assertIsNone(span2.parent)

            # check attributes
            self.assert_span_has_attributes(
                span,
                {
                    SpanAttributes.NET_PEER_IP:
                    "[::1]",
                    SpanAttributes.NET_PEER_NAME:
                    "localhost",
                    SpanAttributes.RPC_METHOD:
                    "handler",
                    SpanAttributes.RPC_SERVICE:
                    "TestServicer",
                    SpanAttributes.RPC_SYSTEM:
                    "grpc",
                    SpanAttributes.RPC_GRPC_STATUS_CODE:
                    grpc.StatusCode.OK.value[0],
                },
            )
    def test_abort(self):
        """Check that we can catch an abort properly"""

        # Intercept gRPC calls...
        interceptor = server_interceptor()

        # our detailed failure message
        failure_message = "This is a test failure"

        # aborting RPC handler
        def handler(request, context):
            context.abort(grpc.StatusCode.FAILED_PRECONDITION, failure_message)

        server = grpc.server(
            futures.ThreadPoolExecutor(max_workers=1),
            options=(("grpc.so_reuseport", 0), ),
            interceptors=[interceptor],
        )

        server.add_generic_rpc_handlers((UnaryUnaryRpcHandler(handler), ))

        port = server.add_insecure_port("[::]:0")
        channel = grpc.insecure_channel("localhost:{:d}".format(port))

        rpc_call = "TestServicer/handler"

        server.start()
        # unfortunately, these are just bare exceptions in grpc...
        with self.assertRaises(Exception):
            channel.unary_unary(rpc_call)(b"")
        server.stop(None)

        spans_list = self.memory_exporter.get_finished_spans()
        self.assertEqual(len(spans_list), 1)
        span = spans_list[0]

        self.assertEqual(span.name, rpc_call)
        self.assertIs(span.kind, trace.SpanKind.SERVER)

        # Check version and name in span's instrumentation info
        self.check_span_instrumentation_info(
            span, opentelemetry.instrumentation.grpc)

        # make sure this span errored, with the right status and detail
        self.assertEqual(span.status.status_code, StatusCode.ERROR)
        self.assertEqual(
            span.status.description,
            "{}:{}".format(grpc.StatusCode.FAILED_PRECONDITION,
                           failure_message),
        )

        # Check attributes
        self.assert_span_has_attributes(
            span,
            {
                SpanAttributes.NET_PEER_IP:
                "[::1]",
                SpanAttributes.NET_PEER_NAME:
                "localhost",
                SpanAttributes.RPC_METHOD:
                "handler",
                SpanAttributes.RPC_SERVICE:
                "TestServicer",
                SpanAttributes.RPC_SYSTEM:
                "grpc",
                SpanAttributes.RPC_GRPC_STATUS_CODE:
                grpc.StatusCode.FAILED_PRECONDITION.value[0],
            },
        )
    def test_create_two_spans_streaming(self):
        """Verify that the interceptor captures sub spans in a
        streaming call, within the given trace"""
        class TwoSpanServicer(GRPCTestServerServicer):
            # pylint:disable=C0103
            def ServerStreamingMethod(self, request, context):

                # create another span
                tracer = trace.get_tracer(__name__)
                with tracer.start_as_current_span("child") as child:
                    child.add_event("child event")

                for data in ("one", "two", "three"):
                    yield Response(
                        server_id=request.client_id,
                        response_data=data,
                    )

        # Intercept gRPC calls...
        interceptor = server_interceptor()

        # setup the server
        server = grpc.server(
            futures.ThreadPoolExecutor(max_workers=1),
            options=(("grpc.so_reuseport", 0), ),
            interceptors=[interceptor],
        )
        add_GRPCTestServerServicer_to_server(TwoSpanServicer(), server)
        port = server.add_insecure_port("[::]:0")
        channel = grpc.insecure_channel("localhost:{:d}".format(port))

        # setup the RPC
        rpc_call = "/GRPCTestServer/ServerStreamingMethod"
        request = Request(client_id=1, request_data="test")
        msg = request.SerializeToString()
        try:
            server.start()
            list(channel.unary_stream(rpc_call)(msg))
        finally:
            server.stop(None)

        spans_list = self.memory_exporter.get_finished_spans()
        self.assertEqual(len(spans_list), 2)
        child_span = spans_list[0]
        parent_span = spans_list[1]

        self.assertEqual(parent_span.name, rpc_call)
        self.assertIs(parent_span.kind, trace.SpanKind.SERVER)

        # Check version and name in span's instrumentation info
        self.check_span_instrumentation_info(
            parent_span, opentelemetry.instrumentation.grpc)

        # Check attributes
        self.assert_span_has_attributes(
            parent_span,
            {
                SpanAttributes.NET_PEER_IP: "[::1]",
                SpanAttributes.NET_PEER_NAME: "localhost",
                SpanAttributes.RPC_METHOD: "ServerStreamingMethod",
                SpanAttributes.RPC_SERVICE: "GRPCTestServer",
                SpanAttributes.RPC_SYSTEM: "grpc",
                SpanAttributes.RPC_GRPC_STATUS_CODE:
                grpc.StatusCode.OK.value[0],
            },
        )

        # Check the child span
        self.assertEqual(child_span.name, "child")
        self.assertEqual(parent_span.context.trace_id,
                         child_span.context.trace_id)
    catalog_addr = os.environ.get('PRODUCT_CATALOG_SERVICE_ADDR', '')
    if catalog_addr == "":
        raise Exception(
            'PRODUCT_CATALOG_SERVICE_ADDR environment variable not set')
    logger.info("product catalog address: " + catalog_addr)

    # Create the gRPC client channel to ProductCatalog (server).
    channel = grpc.insecure_channel(catalog_addr)

    # OpenTelemetry client interceptor passes trace contexts to the server.
    channel = intercept_channel(
        channel, client_interceptor(trace.get_tracer_provider()))
    product_catalog_stub = demo_pb2_grpc.ProductCatalogServiceStub(channel)

    # Create the gRPC server for accepting ListRecommendations Requests from frontend (client).
    interceptor = server_interceptor(trace.get_tracer_provider())
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10),
                         interceptors=(interceptor,))

    # Add RecommendationService class to gRPC server.
    service = RecommendationService()
    demo_pb2_grpc.add_RecommendationServiceServicer_to_server(service, server)
    health_pb2_grpc.add_HealthServicer_to_server(service, server)

    # start server
    logger.info("listening on port: " + port)
    server.add_insecure_port('[::]:'+port)
    server.start()

    # keep alive
    try: