Skip to content

Commit e37b5fa

Browse files
committed
Add usage of wrapt according to CR comments
1 parent fedd768 commit e37b5fa

File tree

5 files changed

+48
-22
lines changed

5 files changed

+48
-22
lines changed

instrumentation/opentelemetry-instrumentation-pika/README.rst

+16-4
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,22 @@ Usage
2424
2525
docker run -p 5672:5672 rabbitmq
2626
27-
2827
* Run instrumented task
2928

29+
.. code-block:: python
30+
31+
import pika
32+
from opentelemetry.instrumentation.pika import PikaInstrumentor
33+
34+
PikaInstrumentor().instrument()
35+
36+
connection = pika.BlockingConnection(pika.URLParameters('amqp://localhost'))
37+
channel = connection.channel()
38+
channel.queue_declare(queue='hello')
39+
channel.basic_publish(exchange='', routing_key='hello', body=b'Hello World!')
40+
41+
* PikaInstrumentor also supports instrumentation of a single channel
42+
3043
.. code-block:: python
3144
3245
import pika
@@ -37,13 +50,12 @@ Usage
3750
channel.queue_declare(queue='hello')
3851
3952
pika_instrumentation = PikaInstrumentor()
40-
pika_instrumentation.instrument(channel=channel)
53+
pika_instrumentation.instrument_channel(channel=channel)
4154
4255
4356
channel.basic_publish(exchange='', routing_key='hello', body=b'Hello World!')
4457
45-
pika_instrumentation.uninstrument(channel=channel)
46-
58+
pika_instrumentation.uninstrument_channel(channel=channel)
4759
4860
* PikaInstrumentor also supports instrumentation without creating an object, and receiving a tracer_provider
4961

instrumentation/opentelemetry-instrumentation-pika/setup.cfg

+2
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@ packages=find_namespace:
4040

4141
install_requires =
4242
opentelemetry-api ~= 1.5
43+
wrapt >= 1.0.0, < 2.0.0
4344
pika >= 1.1.0
4445

4546
[options.extras_require]
4647
test =
4748
pytest
49+
wrapt >= 1.0.0, < 2.0.0
4850
opentelemetry-test == 0.24b0
4951

5052
[options.packages.find]

instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/__init__.py

+16-4
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,22 @@
2323
2424
docker run -p 5672:5672 rabbitmq
2525
26-
2726
* Run instrumented task
2827
28+
.. code-block:: python
29+
30+
import pika
31+
from opentelemetry.instrumentation.pika import PikaInstrumentor
32+
33+
PikaInstrumentor().instrument()
34+
35+
connection = pika.BlockingConnection(pika.URLParameters('amqp://localhost'))
36+
channel = connection.channel()
37+
channel.queue_declare(queue='hello')
38+
channel.basic_publish(exchange='', routing_key='hello', body=b'Hello World!')
39+
40+
* PikaInstrumentor also supports instrumentation of a single channel
41+
2942
.. code-block:: python
3043
3144
import pika
@@ -36,13 +49,12 @@
3649
channel.queue_declare(queue='hello')
3750
3851
pika_instrumentation = PikaInstrumentor()
39-
pika_instrumentation.instrument(channel=channel)
52+
pika_instrumentation.instrument_channel(channel=channel)
4053
4154
4255
channel.basic_publish(exchange='', routing_key='hello', body=b'Hello World!')
4356
44-
pika_instrumentation.uninstrument(channel=channel)
45-
57+
pika_instrumentation.uninstrument_channel(channel=channel)
4658
4759
* PikaInstrumentor also supports instrumentation without creating an object, and receiving a tracer_provider
4860

instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/pika_instrumentor.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from logging import getLogger
1515
from typing import Any, Callable, Collection, Dict, Optional
1616

17+
import wrapt
1718
from pika.adapters import BlockingConnection
1819
from pika.channel import Channel
1920

@@ -22,6 +23,7 @@
2223
from opentelemetry.instrumentation.pika import utils
2324
from opentelemetry.instrumentation.pika.package import _instruments
2425
from opentelemetry.instrumentation.pika.version import __version__
26+
from opentelemetry.instrumentation.utils import unwrap
2527
from opentelemetry.trace import Tracer, TracerProvider
2628

2729
_LOG = getLogger(__name__)
@@ -93,25 +95,25 @@ def uninstrument_channel(channel: Channel) -> None:
9395
if hasattr(callback, "_original_callback"):
9496
channel._impl._consumers[key] = callback._original_callback
9597
PikaInstrumentor._uninstrument_channel_functions(channel)
98+
if hasattr(channel, "__opentelemetry_tracer"):
99+
delattr(channel, "__opentelemetry_tracer")
96100

97101
def _decorate_channel_function(
98102
self, tracer_provider: Optional[TracerProvider]
99103
) -> None:
100-
self.original_channel_func = BlockingConnection.channel
101-
102-
def _wrapper(*args, **kwargs):
103-
channel = self.original_channel_func(*args, **kwargs)
104+
def wrapper(wrapped, instance, args, kwargs):
105+
channel = wrapped(*args, **kwargs)
104106
self.instrument_channel(channel, tracer_provider=tracer_provider)
105107
return channel
106108

107-
BlockingConnection.channel = _wrapper
109+
wrapt.wrap_function_wrapper(BlockingConnection, "channel", wrapper)
108110

109111
def _instrument(self, **kwargs: Dict[str, Any]) -> None:
110112
tracer_provider: TracerProvider = kwargs.get("tracer_provider", None)
111113
self._decorate_channel_function(tracer_provider)
112114

113115
def _uninstrument(self, **kwargs: Dict[str, Any]) -> None:
114-
BlockingConnection.channel = self.original_channel_func
116+
unwrap(BlockingConnection, "channel")
115117

116118
def instrumentation_dependencies(self) -> Collection[str]:
117119
return _instruments

instrumentation/opentelemetry-instrumentation-pika/tests/test_pika_instrumentation.py

+6-8
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from pika.adapters import BaseConnection, BlockingConnection
1717
from pika.channel import Channel
18+
from wrapt import BoundFunctionWrapper
1819

1920
from opentelemetry.instrumentation.pika import PikaInstrumentor
2021
from opentelemetry.trace import Tracer
@@ -28,15 +29,15 @@ def setUp(self) -> None:
2829
self.channel._impl._consumers = {"mock_key": self.mock_callback}
2930

3031
def test_instrument_api(self) -> None:
31-
original_channel = BlockingConnection.channel
3232
instrumentation = PikaInstrumentor()
3333
instrumentation.instrument()
34-
self.assertTrue(hasattr(instrumentation, "original_channel_func"))
35-
self.assertEqual(
36-
original_channel, instrumentation.original_channel_func
34+
self.assertTrue(
35+
isinstance(BlockingConnection.channel, BoundFunctionWrapper)
3736
)
3837
instrumentation.uninstrument(channel=self.channel)
39-
self.assertEqual(original_channel, BlockingConnection.channel)
38+
self.assertFalse(
39+
isinstance(BlockingConnection.channel, BoundFunctionWrapper)
40+
)
4041

4142
@mock.patch(
4243
"opentelemetry.instrumentation.pika.PikaInstrumentor._instrument_channel_functions"
@@ -91,9 +92,6 @@ def test_instrument_basic_publish(
9192
self.assertEqual(
9293
self.channel.basic_publish, decorate_basic_publish.return_value
9394
)
94-
self.assertEqual(
95-
self.channel.basic_publish._original_function, original_function
96-
)
9795

9896
def test_uninstrument_channel_functions(self) -> None:
9997
original_function = self.channel.basic_publish

0 commit comments

Comments
 (0)