We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Typos in gRPC instrumentation example codes
**Describe your environment**

* Platform: any
* Python version: any
* Library version: main HEAD as of Aug 24th

**Steps to reproduce**
See [documents for gRPC instrumentation](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/grpc/grpc.html)

**What is the expected behavior?**
For client instrumentation example, I would see either of the followings:

1. `GrpcInstrumentorClient().instrument()` is called without return value assignment.
2. Get the return value of `GrpcInstrumentorClient()` and call `instrument()` method of it.

**What is the actual behavior?**

I see the following example codes.

In the [Usage Client](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/grpc/grpc.html#usage-client) section:

```python
instrumentor = GrpcInstrumentorClient().instrument()
```

And in the [GrpcInstrumentorClient class document](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/grpc/grpc.html#usage-client):

```python
grpc_client_instrumentor = GrpcInstrumentorClient()
grpc.client_instrumentor.instrument()
```

where 2nd line is calling non existing package. It should be typo of the variable defined in 1st line.

**Additional context**

I was trying implement the code to fix #373 and found this issue, so I created separate issue here. I'll create a PR for this shortly.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py`
Content:
```
1 # Copyright The OpenTelemetry Authors
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 # pylint:disable=no-name-in-module
16 # pylint:disable=relative-beyond-top-level
17 # pylint:disable=import-error
18 # pylint:disable=no-self-use
19 """
20 Usage Client
21 ------------
22 .. code-block:: python
23 
24     import logging
25 
26     import grpc
27 
28     from opentelemetry import trace
29     from opentelemetry.instrumentation.grpc import GrpcInstrumentorClient
30     from opentelemetry.sdk.trace import TracerProvider
31     from opentelemetry.sdk.trace.export import (
32         ConsoleSpanExporter,
33         SimpleSpanProcessor,
34     )
35 
36     try:
37         from .gen import helloworld_pb2, helloworld_pb2_grpc
38     except ImportError:
39         from gen import helloworld_pb2, helloworld_pb2_grpc
40 
41     trace.set_tracer_provider(TracerProvider())
42     trace.get_tracer_provider().add_span_processor(
43         SimpleSpanProcessor(ConsoleSpanExporter())
44     )
45 
46     instrumentor = GrpcInstrumentorClient().instrument()
47 
48     def run():
49         with grpc.insecure_channel("localhost:50051") as channel:
50 
51             stub = helloworld_pb2_grpc.GreeterStub(channel)
52             response = stub.SayHello(helloworld_pb2.HelloRequest(name="YOU"))
53 
54         print("Greeter client received: " + response.message)
55 
56 
57     if __name__ == "__main__":
58         logging.basicConfig()
59         run()
60 
61 Usage Server
62 ------------
63 .. code-block:: python
64 
65     import logging
66     from concurrent import futures
67 
68     import grpc
69 
70     from opentelemetry import trace
71     from opentelemetry.instrumentation.grpc import GrpcInstrumentorServer
72     from opentelemetry.sdk.trace import TracerProvider
73     from opentelemetry.sdk.trace.export import (
74         ConsoleSpanExporter,
75         SimpleSpanProcessor,
76     )
77 
78     try:
79         from .gen import helloworld_pb2, helloworld_pb2_grpc
80     except ImportError:
81         from gen import helloworld_pb2, helloworld_pb2_grpc
82 
83     trace.set_tracer_provider(TracerProvider())
84     trace.get_tracer_provider().add_span_processor(
85         SimpleSpanProcessor(ConsoleSpanExporter())
86     )
87 
88     grpc_server_instrumentor = GrpcInstrumentorServer()
89     grpc_server_instrumentor.instrument()
90 
91     class Greeter(helloworld_pb2_grpc.GreeterServicer):
92         def SayHello(self, request, context):
93             return helloworld_pb2.HelloReply(message="Hello, %s!" % request.name)
94 
95 
96     def serve():
97 
98         server = grpc.server(futures.ThreadPoolExecutor())
99 
100         helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
101         server.add_insecure_port("[::]:50051")
102         server.start()
103         server.wait_for_termination()
104 
105 
106     if __name__ == "__main__":
107         logging.basicConfig()
108         serve()
109 
110 You can also add the instrumentor manually, rather than using
111 :py:class:`~opentelemetry.instrumentation.grpc.GrpcInstrumentorServer`:
112 
113 .. code-block:: python
114 
115     from opentelemetry.instrumentation.grpc import server_interceptor
116 
117     server = grpc.server(futures.ThreadPoolExecutor(),
118                          interceptors = [server_interceptor()])
119 
120 """
121 from typing import Collection
122 
123 import grpc  # pylint:disable=import-self
124 from wrapt import wrap_function_wrapper as _wrap
125 
126 from opentelemetry import trace
127 from opentelemetry.instrumentation.grpc.grpcext import intercept_channel
128 from opentelemetry.instrumentation.grpc.package import _instruments
129 from opentelemetry.instrumentation.grpc.version import __version__
130 from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
131 from opentelemetry.instrumentation.utils import unwrap
132 
133 # pylint:disable=import-outside-toplevel
134 # pylint:disable=import-self
135 # pylint:disable=unused-argument
136 
137 
138 class GrpcInstrumentorServer(BaseInstrumentor):
139     """
140     Globally instrument the grpc server.
141 
142     Usage::
143 
144         grpc_server_instrumentor = GrpcInstrumentorServer()
145         grpc_server_instrumentor.instrument()
146 
147     """
148 
149     # pylint:disable=attribute-defined-outside-init, redefined-outer-name
150 
151     def instrumentation_dependencies(self) -> Collection[str]:
152         return _instruments
153 
154     def _instrument(self, **kwargs):
155         self._original_func = grpc.server
156         tracer_provider = kwargs.get("tracer_provider")
157 
158         def server(*args, **kwargs):
159             if "interceptors" in kwargs:
160                 # add our interceptor as the first
161                 kwargs["interceptors"].insert(
162                     0, server_interceptor(tracer_provider=tracer_provider)
163                 )
164             else:
165                 kwargs["interceptors"] = [
166                     server_interceptor(tracer_provider=tracer_provider)
167                 ]
168             return self._original_func(*args, **kwargs)
169 
170         grpc.server = server
171 
172     def _uninstrument(self, **kwargs):
173         grpc.server = self._original_func
174 
175 
176 class GrpcInstrumentorClient(BaseInstrumentor):
177     """
178     Globally instrument the grpc client
179 
180     Usage::
181 
182         grpc_client_instrumentor = GrpcInstrumentorClient()
183         grpc.client_instrumentor.instrument()
184 
185     """
186 
187     # Figures out which channel type we need to wrap
188     def _which_channel(self, kwargs):
189         # handle legacy argument
190         if "channel_type" in kwargs:
191             if kwargs.get("channel_type") == "secure":
192                 return ("secure_channel",)
193             return ("insecure_channel",)
194 
195         # handle modern arguments
196         types = []
197         for ctype in ("secure_channel", "insecure_channel"):
198             if kwargs.get(ctype, True):
199                 types.append(ctype)
200 
201         return tuple(types)
202 
203     def instrumentation_dependencies(self) -> Collection[str]:
204         return _instruments
205 
206     def _instrument(self, **kwargs):
207         for ctype in self._which_channel(kwargs):
208             _wrap(
209                 "grpc",
210                 ctype,
211                 self.wrapper_fn,
212             )
213 
214     def _uninstrument(self, **kwargs):
215         for ctype in self._which_channel(kwargs):
216             unwrap(grpc, ctype)
217 
218     def wrapper_fn(self, original_func, instance, args, kwargs):
219         channel = original_func(*args, **kwargs)
220         tracer_provider = kwargs.get("tracer_provider")
221         return intercept_channel(
222             channel,
223             client_interceptor(tracer_provider=tracer_provider),
224         )
225 
226 
227 def client_interceptor(tracer_provider=None):
228     """Create a gRPC client channel interceptor.
229 
230     Args:
231         tracer: The tracer to use to create client-side spans.
232 
233     Returns:
234         An invocation-side interceptor object.
235     """
236     from . import _client
237 
238     tracer = trace.get_tracer(__name__, __version__, tracer_provider)
239 
240     return _client.OpenTelemetryClientInterceptor(tracer)
241 
242 
243 def server_interceptor(tracer_provider=None):
244     """Create a gRPC server interceptor.
245 
246     Args:
247         tracer: The tracer to use to create server-side spans.
248 
249     Returns:
250         A service-side interceptor object.
251     """
252     from . import _server
253 
254     tracer = trace.get_tracer(__name__, __version__, tracer_provider)
255 
256     return _server.OpenTelemetryServerInterceptor(tracer)
257
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py
--- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py
+++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py
@@ -43,7 +43,8 @@
         SimpleSpanProcessor(ConsoleSpanExporter())
     )
 
-    instrumentor = GrpcInstrumentorClient().instrument()
+    grpc_client_instrumentor = GrpcInstrumentorClient()
+    grpc_client_instrumentor.instrument()
 
     def run():
         with grpc.insecure_channel("localhost:50051") as channel:
@@ -180,7 +181,7 @@
     Usage::
 
         grpc_client_instrumentor = GrpcInstrumentorClient()
-        grpc.client_instrumentor.instrument()
+        grpc_client_instrumentor.instrument()
 
     """

{"golden_diff": "diff --git a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py\n--- a/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py\n+++ b/instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py\n@@ -43,7 +43,8 @@\n         SimpleSpanProcessor(ConsoleSpanExporter())\n     )\n \n-    instrumentor = GrpcInstrumentorClient().instrument()\n+    grpc_client_instrumentor = GrpcInstrumentorClient()\n+    grpc_client_instrumentor.instrument()\n \n     def run():\n         with grpc.insecure_channel(\"localhost:50051\") as channel:\n@@ -180,7 +181,7 @@\n     Usage::\n \n         grpc_client_instrumentor = GrpcInstrumentorClient()\n-        grpc.client_instrumentor.instrument()\n+        grpc_client_instrumentor.instrument()\n \n     \"\"\"\n", "issue": "Typos in gRPC instrumentation example codes\n**Describe your environment**\r\n\r\n* Platform: any\r\n* Python version: any\r\n* Library version: main HEAD as of Aug 24th\r\n\r\n**Steps to reproduce**\r\nSee [documents for gRPC instrumentation](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/grpc/grpc.html)\r\n\r\n**What is the expected behavior?**\r\nFor client instrumentation example, I would see either of the followings:\r\n\r\n1. `GrpcInstrumentorClient().instrument()` is called without return value assignment.\r\n2. Get the return value of `GrpcInstrumentorClient()` and call `instrument()` method of it.\r\n\r\n**What is the actual behavior?**\r\n\r\nI see the following example codes.\r\n\r\nIn the [Usage Client](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/grpc/grpc.html#usage-client) section:\r\n\r\n```python\r\ninstrumentor = GrpcInstrumentorClient().instrument()\r\n```\r\n\r\nAnd in the [GrpcInstrumentorClient class document](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/grpc/grpc.html#usage-client):\r\n\r\n```python\r\ngrpc_client_instrumentor = GrpcInstrumentorClient()\r\ngrpc.client_instrumentor.instrument()\r\n```\r\n\r\nwhere 2nd line is calling non existing package. It should be typo of the variable defined in 1st line.\r\n\r\n**Additional context**\r\n\r\nI was trying implement the code to fix #373 and found this issue, so I created separate issue here. I'll create a PR for this shortly.\n", "before_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# pylint:disable=no-name-in-module\n# pylint:disable=relative-beyond-top-level\n# pylint:disable=import-error\n# pylint:disable=no-self-use\n\"\"\"\nUsage Client\n------------\n.. code-block:: python\n\n    import logging\n\n    import grpc\n\n    from opentelemetry import trace\n    from opentelemetry.instrumentation.grpc import GrpcInstrumentorClient\n    from opentelemetry.sdk.trace import TracerProvider\n    from opentelemetry.sdk.trace.export import (\n        ConsoleSpanExporter,\n        SimpleSpanProcessor,\n    )\n\n    try:\n        from .gen import helloworld_pb2, helloworld_pb2_grpc\n    except ImportError:\n        from gen import helloworld_pb2, helloworld_pb2_grpc\n\n    trace.set_tracer_provider(TracerProvider())\n    trace.get_tracer_provider().add_span_processor(\n        SimpleSpanProcessor(ConsoleSpanExporter())\n    )\n\n    instrumentor = GrpcInstrumentorClient().instrument()\n\n    def run():\n        with grpc.insecure_channel(\"localhost:50051\") as channel:\n\n            stub = helloworld_pb2_grpc.GreeterStub(channel)\n            response = stub.SayHello(helloworld_pb2.HelloRequest(name=\"YOU\"))\n\n        print(\"Greeter client received: \" + response.message)\n\n\n    if __name__ == \"__main__\":\n        logging.basicConfig()\n        run()\n\nUsage Server\n------------\n.. code-block:: python\n\n    import logging\n    from concurrent import futures\n\n    import grpc\n\n    from opentelemetry import trace\n    from opentelemetry.instrumentation.grpc import GrpcInstrumentorServer\n    from opentelemetry.sdk.trace import TracerProvider\n    from opentelemetry.sdk.trace.export import (\n        ConsoleSpanExporter,\n        SimpleSpanProcessor,\n    )\n\n    try:\n        from .gen import helloworld_pb2, helloworld_pb2_grpc\n    except ImportError:\n        from gen import helloworld_pb2, helloworld_pb2_grpc\n\n    trace.set_tracer_provider(TracerProvider())\n    trace.get_tracer_provider().add_span_processor(\n        SimpleSpanProcessor(ConsoleSpanExporter())\n    )\n\n    grpc_server_instrumentor = GrpcInstrumentorServer()\n    grpc_server_instrumentor.instrument()\n\n    class Greeter(helloworld_pb2_grpc.GreeterServicer):\n        def SayHello(self, request, context):\n            return helloworld_pb2.HelloReply(message=\"Hello, %s!\" % request.name)\n\n\n    def serve():\n\n        server = grpc.server(futures.ThreadPoolExecutor())\n\n        helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)\n        server.add_insecure_port(\"[::]:50051\")\n        server.start()\n        server.wait_for_termination()\n\n\n    if __name__ == \"__main__\":\n        logging.basicConfig()\n        serve()\n\nYou can also add the instrumentor manually, rather than using\n:py:class:`~opentelemetry.instrumentation.grpc.GrpcInstrumentorServer`:\n\n.. code-block:: python\n\n    from opentelemetry.instrumentation.grpc import server_interceptor\n\n    server = grpc.server(futures.ThreadPoolExecutor(),\n                         interceptors = [server_interceptor()])\n\n\"\"\"\nfrom typing import Collection\n\nimport grpc  # pylint:disable=import-self\nfrom wrapt import wrap_function_wrapper as _wrap\n\nfrom opentelemetry import trace\nfrom opentelemetry.instrumentation.grpc.grpcext import intercept_channel\nfrom opentelemetry.instrumentation.grpc.package import _instruments\nfrom opentelemetry.instrumentation.grpc.version import __version__\nfrom opentelemetry.instrumentation.instrumentor import BaseInstrumentor\nfrom opentelemetry.instrumentation.utils import unwrap\n\n# pylint:disable=import-outside-toplevel\n# pylint:disable=import-self\n# pylint:disable=unused-argument\n\n\nclass GrpcInstrumentorServer(BaseInstrumentor):\n    \"\"\"\n    Globally instrument the grpc server.\n\n    Usage::\n\n        grpc_server_instrumentor = GrpcInstrumentorServer()\n        grpc_server_instrumentor.instrument()\n\n    \"\"\"\n\n    # pylint:disable=attribute-defined-outside-init, redefined-outer-name\n\n    def instrumentation_dependencies(self) -> Collection[str]:\n        return _instruments\n\n    def _instrument(self, **kwargs):\n        self._original_func = grpc.server\n        tracer_provider = kwargs.get(\"tracer_provider\")\n\n        def server(*args, **kwargs):\n            if \"interceptors\" in kwargs:\n                # add our interceptor as the first\n                kwargs[\"interceptors\"].insert(\n                    0, server_interceptor(tracer_provider=tracer_provider)\n                )\n            else:\n                kwargs[\"interceptors\"] = [\n                    server_interceptor(tracer_provider=tracer_provider)\n                ]\n            return self._original_func(*args, **kwargs)\n\n        grpc.server = server\n\n    def _uninstrument(self, **kwargs):\n        grpc.server = self._original_func\n\n\nclass GrpcInstrumentorClient(BaseInstrumentor):\n    \"\"\"\n    Globally instrument the grpc client\n\n    Usage::\n\n        grpc_client_instrumentor = GrpcInstrumentorClient()\n        grpc.client_instrumentor.instrument()\n\n    \"\"\"\n\n    # Figures out which channel type we need to wrap\n    def _which_channel(self, kwargs):\n        # handle legacy argument\n        if \"channel_type\" in kwargs:\n            if kwargs.get(\"channel_type\") == \"secure\":\n                return (\"secure_channel\",)\n            return (\"insecure_channel\",)\n\n        # handle modern arguments\n        types = []\n        for ctype in (\"secure_channel\", \"insecure_channel\"):\n            if kwargs.get(ctype, True):\n                types.append(ctype)\n\n        return tuple(types)\n\n    def instrumentation_dependencies(self) -> Collection[str]:\n        return _instruments\n\n    def _instrument(self, **kwargs):\n        for ctype in self._which_channel(kwargs):\n            _wrap(\n                \"grpc\",\n                ctype,\n                self.wrapper_fn,\n            )\n\n    def _uninstrument(self, **kwargs):\n        for ctype in self._which_channel(kwargs):\n            unwrap(grpc, ctype)\n\n    def wrapper_fn(self, original_func, instance, args, kwargs):\n        channel = original_func(*args, **kwargs)\n        tracer_provider = kwargs.get(\"tracer_provider\")\n        return intercept_channel(\n            channel,\n            client_interceptor(tracer_provider=tracer_provider),\n        )\n\n\ndef client_interceptor(tracer_provider=None):\n    \"\"\"Create a gRPC client channel interceptor.\n\n    Args:\n        tracer: The tracer to use to create client-side spans.\n\n    Returns:\n        An invocation-side interceptor object.\n    \"\"\"\n    from . import _client\n\n    tracer = trace.get_tracer(__name__, __version__, tracer_provider)\n\n    return _client.OpenTelemetryClientInterceptor(tracer)\n\n\ndef server_interceptor(tracer_provider=None):\n    \"\"\"Create a gRPC server interceptor.\n\n    Args:\n        tracer: The tracer to use to create server-side spans.\n\n    Returns:\n        A service-side interceptor object.\n    \"\"\"\n    from . import _server\n\n    tracer = trace.get_tracer(__name__, __version__, tracer_provider)\n\n    return _server.OpenTelemetryServerInterceptor(tracer)\n", "path": "instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py"}], "after_files": [{"content": "# Copyright The OpenTelemetry Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n# pylint:disable=no-name-in-module\n# pylint:disable=relative-beyond-top-level\n# pylint:disable=import-error\n# pylint:disable=no-self-use\n\"\"\"\nUsage Client\n------------\n.. code-block:: python\n\n    import logging\n\n    import grpc\n\n    from opentelemetry import trace\n    from opentelemetry.instrumentation.grpc import GrpcInstrumentorClient\n    from opentelemetry.sdk.trace import TracerProvider\n    from opentelemetry.sdk.trace.export import (\n        ConsoleSpanExporter,\n        SimpleSpanProcessor,\n    )\n\n    try:\n        from .gen import helloworld_pb2, helloworld_pb2_grpc\n    except ImportError:\n        from gen import helloworld_pb2, helloworld_pb2_grpc\n\n    trace.set_tracer_provider(TracerProvider())\n    trace.get_tracer_provider().add_span_processor(\n        SimpleSpanProcessor(ConsoleSpanExporter())\n    )\n\n    grpc_client_instrumentor = GrpcInstrumentorClient()\n    grpc_client_instrumentor.instrument()\n\n    def run():\n        with grpc.insecure_channel(\"localhost:50051\") as channel:\n\n            stub = helloworld_pb2_grpc.GreeterStub(channel)\n            response = stub.SayHello(helloworld_pb2.HelloRequest(name=\"YOU\"))\n\n        print(\"Greeter client received: \" + response.message)\n\n\n    if __name__ == \"__main__\":\n        logging.basicConfig()\n        run()\n\nUsage Server\n------------\n.. code-block:: python\n\n    import logging\n    from concurrent import futures\n\n    import grpc\n\n    from opentelemetry import trace\n    from opentelemetry.instrumentation.grpc import GrpcInstrumentorServer\n    from opentelemetry.sdk.trace import TracerProvider\n    from opentelemetry.sdk.trace.export import (\n        ConsoleSpanExporter,\n        SimpleSpanProcessor,\n    )\n\n    try:\n        from .gen import helloworld_pb2, helloworld_pb2_grpc\n    except ImportError:\n        from gen import helloworld_pb2, helloworld_pb2_grpc\n\n    trace.set_tracer_provider(TracerProvider())\n    trace.get_tracer_provider().add_span_processor(\n        SimpleSpanProcessor(ConsoleSpanExporter())\n    )\n\n    grpc_server_instrumentor = GrpcInstrumentorServer()\n    grpc_server_instrumentor.instrument()\n\n    class Greeter(helloworld_pb2_grpc.GreeterServicer):\n        def SayHello(self, request, context):\n            return helloworld_pb2.HelloReply(message=\"Hello, %s!\" % request.name)\n\n\n    def serve():\n\n        server = grpc.server(futures.ThreadPoolExecutor())\n\n        helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)\n        server.add_insecure_port(\"[::]:50051\")\n        server.start()\n        server.wait_for_termination()\n\n\n    if __name__ == \"__main__\":\n        logging.basicConfig()\n        serve()\n\nYou can also add the instrumentor manually, rather than using\n:py:class:`~opentelemetry.instrumentation.grpc.GrpcInstrumentorServer`:\n\n.. code-block:: python\n\n    from opentelemetry.instrumentation.grpc import server_interceptor\n\n    server = grpc.server(futures.ThreadPoolExecutor(),\n                         interceptors = [server_interceptor()])\n\n\"\"\"\nfrom typing import Collection\n\nimport grpc  # pylint:disable=import-self\nfrom wrapt import wrap_function_wrapper as _wrap\n\nfrom opentelemetry import trace\nfrom opentelemetry.instrumentation.grpc.grpcext import intercept_channel\nfrom opentelemetry.instrumentation.grpc.package import _instruments\nfrom opentelemetry.instrumentation.grpc.version import __version__\nfrom opentelemetry.instrumentation.instrumentor import BaseInstrumentor\nfrom opentelemetry.instrumentation.utils import unwrap\n\n# pylint:disable=import-outside-toplevel\n# pylint:disable=import-self\n# pylint:disable=unused-argument\n\n\nclass GrpcInstrumentorServer(BaseInstrumentor):\n    \"\"\"\n    Globally instrument the grpc server.\n\n    Usage::\n\n        grpc_server_instrumentor = GrpcInstrumentorServer()\n        grpc_server_instrumentor.instrument()\n\n    \"\"\"\n\n    # pylint:disable=attribute-defined-outside-init, redefined-outer-name\n\n    def instrumentation_dependencies(self) -> Collection[str]:\n        return _instruments\n\n    def _instrument(self, **kwargs):\n        self._original_func = grpc.server\n        tracer_provider = kwargs.get(\"tracer_provider\")\n\n        def server(*args, **kwargs):\n            if \"interceptors\" in kwargs:\n                # add our interceptor as the first\n                kwargs[\"interceptors\"].insert(\n                    0, server_interceptor(tracer_provider=tracer_provider)\n                )\n            else:\n                kwargs[\"interceptors\"] = [\n                    server_interceptor(tracer_provider=tracer_provider)\n                ]\n            return self._original_func(*args, **kwargs)\n\n        grpc.server = server\n\n    def _uninstrument(self, **kwargs):\n        grpc.server = self._original_func\n\n\nclass GrpcInstrumentorClient(BaseInstrumentor):\n    \"\"\"\n    Globally instrument the grpc client\n\n    Usage::\n\n        grpc_client_instrumentor = GrpcInstrumentorClient()\n        grpc_client_instrumentor.instrument()\n\n    \"\"\"\n\n    # Figures out which channel type we need to wrap\n    def _which_channel(self, kwargs):\n        # handle legacy argument\n        if \"channel_type\" in kwargs:\n            if kwargs.get(\"channel_type\") == \"secure\":\n                return (\"secure_channel\",)\n            return (\"insecure_channel\",)\n\n        # handle modern arguments\n        types = []\n        for ctype in (\"secure_channel\", \"insecure_channel\"):\n            if kwargs.get(ctype, True):\n                types.append(ctype)\n\n        return tuple(types)\n\n    def instrumentation_dependencies(self) -> Collection[str]:\n        return _instruments\n\n    def _instrument(self, **kwargs):\n        for ctype in self._which_channel(kwargs):\n            _wrap(\n                \"grpc\",\n                ctype,\n                self.wrapper_fn,\n            )\n\n    def _uninstrument(self, **kwargs):\n        for ctype in self._which_channel(kwargs):\n            unwrap(grpc, ctype)\n\n    def wrapper_fn(self, original_func, instance, args, kwargs):\n        channel = original_func(*args, **kwargs)\n        tracer_provider = kwargs.get(\"tracer_provider\")\n        return intercept_channel(\n            channel,\n            client_interceptor(tracer_provider=tracer_provider),\n        )\n\n\ndef client_interceptor(tracer_provider=None):\n    \"\"\"Create a gRPC client channel interceptor.\n\n    Args:\n        tracer: The tracer to use to create client-side spans.\n\n    Returns:\n        An invocation-side interceptor object.\n    \"\"\"\n    from . import _client\n\n    tracer = trace.get_tracer(__name__, __version__, tracer_provider)\n\n    return _client.OpenTelemetryClientInterceptor(tracer)\n\n\ndef server_interceptor(tracer_provider=None):\n    \"\"\"Create a gRPC server interceptor.\n\n    Args:\n        tracer: The tracer to use to create server-side spans.\n\n    Returns:\n        A service-side interceptor object.\n    \"\"\"\n    from . import _server\n\n    tracer = trace.get_tracer(__name__, __version__, tracer_provider)\n\n    return _server.OpenTelemetryServerInterceptor(tracer)\n", "path": "instrumentation/opentelemetry-instrumentation-grpc/src/opentelemetry/instrumentation/grpc/__init__.py"}]}