@@ -108,7 +108,7 @@ def serve():
108108 logging.basicConfig()
109109 serve()
110110
111- You can also add the instrumentor manually, rather than using
111+ You can also add the interceptor manually, rather than using
112112:py:class:`~opentelemetry.instrumentation.grpc.GrpcInstrumentorServer`:
113113
114114.. code-block:: python
@@ -118,6 +118,64 @@ def serve():
118118 server = grpc.server(futures.ThreadPoolExecutor(),
119119 interceptors = [server_interceptor()])
120120
121+ Usage Aio Server
122+ ------------
123+ .. code-block:: python
124+
125+ import logging
126+ import asyncio
127+
128+ import grpc
129+
130+ from opentelemetry import trace
131+ from opentelemetry.instrumentation.grpc import GrpcAioInstrumentorServer
132+ from opentelemetry.sdk.trace import TracerProvider
133+ from opentelemetry.sdk.trace.export import (
134+ ConsoleSpanExporter,
135+ SimpleSpanProcessor,
136+ )
137+
138+ try:
139+ from .gen import helloworld_pb2, helloworld_pb2_grpc
140+ except ImportError:
141+ from gen import helloworld_pb2, helloworld_pb2_grpc
142+
143+ trace.set_tracer_provider(TracerProvider())
144+ trace.get_tracer_provider().add_span_processor(
145+ SimpleSpanProcessor(ConsoleSpanExporter())
146+ )
147+
148+ grpc_server_instrumentor = GrpcAioInstrumentorServer()
149+ grpc_server_instrumentor.instrument()
150+
151+ class Greeter(helloworld_pb2_grpc.GreeterServicer):
152+ async def SayHello(self, request, context):
153+ return helloworld_pb2.HelloReply(message="Hello, %s!" % request.name)
154+
155+
156+ async def serve():
157+
158+ server = grpc.aio.server()
159+
160+ helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
161+ server.add_insecure_port("[::]:50051")
162+ await server.start()
163+ await server.wait_for_termination()
164+
165+
166+ if __name__ == "__main__":
167+ logging.basicConfig()
168+ asyncio.run(serve())
169+
170+ You can also add the interceptor manually, rather than using
171+ :py:class:`~opentelemetry.instrumentation.grpc.GrpcAioInstrumentorServer`:
172+
173+ .. code-block:: python
174+
175+ from opentelemetry.instrumentation.grpc import aio_server_interceptor
176+
177+ server = grpc.aio.server(interceptors = [aio_server_interceptor()])
178+
121179"""
122180from typing import Collection
123181
@@ -174,6 +232,44 @@ def _uninstrument(self, **kwargs):
174232 grpc .server = self ._original_func
175233
176234
235+ class GrpcAioInstrumentorServer (BaseInstrumentor ):
236+ """
237+ Globally instrument the grpc.aio server.
238+
239+ Usage::
240+
241+ grpc_aio_server_instrumentor = GrpcAioInstrumentorServer()
242+ grpc_aio_server_instrumentor.instrument()
243+
244+ """
245+
246+ # pylint:disable=attribute-defined-outside-init, redefined-outer-name
247+
248+ def instrumentation_dependencies (self ) -> Collection [str ]:
249+ return _instruments
250+
251+ def _instrument (self , ** kwargs ):
252+ self ._original_func = grpc .aio .server
253+ tracer_provider = kwargs .get ("tracer_provider" )
254+
255+ def server (* args , ** kwargs ):
256+ if "interceptors" in kwargs :
257+ # add our interceptor as the first
258+ kwargs ["interceptors" ].insert (
259+ 0 , aio_server_interceptor (tracer_provider = tracer_provider )
260+ )
261+ else :
262+ kwargs ["interceptors" ] = [
263+ aio_server_interceptor (tracer_provider = tracer_provider )
264+ ]
265+ return self ._original_func (* args , ** kwargs )
266+
267+ grpc .aio .server = server
268+
269+ def _uninstrument (self , ** kwargs ):
270+ grpc .aio .server = self ._original_func
271+
272+
177273class GrpcInstrumentorClient (BaseInstrumentor ):
178274 """
179275 Globally instrument the grpc client
@@ -255,3 +351,19 @@ def server_interceptor(tracer_provider=None):
255351 tracer = trace .get_tracer (__name__ , __version__ , tracer_provider )
256352
257353 return _server .OpenTelemetryServerInterceptor (tracer )
354+
355+
356+ def aio_server_interceptor (tracer_provider = None ):
357+ """Create a gRPC aio server interceptor.
358+
359+ Args:
360+ tracer: The tracer to use to create server-side spans.
361+
362+ Returns:
363+ A service-side interceptor object.
364+ """
365+ from . import _aio_server
366+
367+ tracer = trace .get_tracer (__name__ , __version__ , tracer_provider )
368+
369+ return _aio_server .OpenTelemetryAioServerInterceptor (tracer )
0 commit comments