Skip to content

Commit 26aa17f

Browse files
authored
Support older pika versions (#837)
* feat: support older pika versions * update tox.ini * update changelog * take version from pika * avoid exception when property name changes * add callback attr name test
1 parent c962da9 commit 26aa17f

File tree

7 files changed

+53
-14
lines changed

7 files changed

+53
-14
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
### Added
1818

1919
- `opentelemetry-instrumentation-aws-lambda` Adds support for configurable flush timeout via `OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT` property. ([#825](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/825))
20+
- `opentelemetry-instrumentation-pika` Adds support for versions between `0.12.0` to `1.0.0`. ([#837](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/837))
2021

2122
### Fixed
2223

Diff for: instrumentation/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
| [opentelemetry-instrumentation-jinja2](./opentelemetry-instrumentation-jinja2) | jinja2 >= 2.7, < 4.0 |
2121
| [opentelemetry-instrumentation-logging](./opentelemetry-instrumentation-logging) | logging |
2222
| [opentelemetry-instrumentation-mysql](./opentelemetry-instrumentation-mysql) | mysql-connector-python ~= 8.0 |
23-
| [opentelemetry-instrumentation-pika](./opentelemetry-instrumentation-pika) | pika >= 1.1.0 |
23+
| [opentelemetry-instrumentation-pika](./opentelemetry-instrumentation-pika) | pika >= 0.12.0 |
2424
| [opentelemetry-instrumentation-psycopg2](./opentelemetry-instrumentation-psycopg2) | psycopg2 >= 2.7.3.1 |
2525
| [opentelemetry-instrumentation-pymemcache](./opentelemetry-instrumentation-pymemcache) | pymemcache ~= 1.3 |
2626
| [opentelemetry-instrumentation-pymongo](./opentelemetry-instrumentation-pymongo) | pymongo ~= 3.1 |

Diff for: instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/package.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
# limitations under the License.
1414
from typing import Collection
1515

16-
_instruments: Collection[str] = ("pika >= 1.1.0",)
16+
_instruments: Collection[str] = ("pika >= 0.12.0",)

Diff for: instrumentation/opentelemetry-instrumentation-pika/src/opentelemetry/instrumentation/pika/pika_instrumentor.py

+24-5
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
from logging import getLogger
1515
from typing import Any, Collection, Dict, Optional
1616

17+
import pika
1718
import wrapt
19+
from packaging import version
1820
from pika.adapters import BlockingConnection
1921
from pika.adapters.blocking_connection import BlockingChannel
2022

@@ -32,7 +34,18 @@
3234
_FUNCTIONS_TO_UNINSTRUMENT = ["basic_publish"]
3335

3436

37+
def _consumer_callback_attribute_name() -> str:
38+
pika_version = version.parse(pika.__version__)
39+
return (
40+
"on_message_callback"
41+
if pika_version >= version.parse("1.0.0")
42+
else "consumer_cb"
43+
)
44+
45+
3546
class PikaInstrumentor(BaseInstrumentor): # type: ignore
47+
CONSUMER_CALLBACK_ATTR = _consumer_callback_attribute_name()
48+
3649
# pylint: disable=attribute-defined-outside-init
3750
@staticmethod
3851
def _instrument_blocking_channel_consumers(
@@ -41,8 +54,12 @@ def _instrument_blocking_channel_consumers(
4154
consume_hook: utils.HookT = utils.dummy_callback,
4255
) -> Any:
4356
for consumer_tag, consumer_info in channel._consumer_infos.items():
57+
callback_attr = PikaInstrumentor.CONSUMER_CALLBACK_ATTR
58+
consumer_callback = getattr(consumer_info, callback_attr, None)
59+
if consumer_callback is None:
60+
continue
4461
decorated_callback = utils._decorate_callback(
45-
consumer_info.on_message_callback,
62+
consumer_callback,
4663
tracer,
4764
consumer_tag,
4865
consume_hook,
@@ -51,9 +68,9 @@ def _instrument_blocking_channel_consumers(
5168
setattr(
5269
decorated_callback,
5370
"_original_callback",
54-
consumer_info.on_message_callback,
71+
consumer_callback,
5572
)
56-
consumer_info.on_message_callback = decorated_callback
73+
setattr(consumer_info, callback_attr, decorated_callback)
5774

5875
@staticmethod
5976
def _instrument_basic_publish(
@@ -126,10 +143,12 @@ def uninstrument_channel(channel: BlockingChannel) -> None:
126143
return
127144

128145
for consumers_tag, client_info in channel._consumer_infos.items():
129-
if hasattr(client_info.on_message_callback, "_original_callback"):
146+
callback_attr = PikaInstrumentor.CONSUMER_CALLBACK_ATTR
147+
consumer_callback = getattr(client_info, callback_attr, None)
148+
if hasattr(consumer_callback, "_original_callback"):
130149
channel._consumer_infos[
131150
consumers_tag
132-
] = client_info.on_message_callback._original_callback
151+
] = consumer_callback._original_callback
133152
PikaInstrumentor._uninstrument_channel_functions(channel)
134153

135154
def _decorate_channel_function(

Diff for: instrumentation/opentelemetry-instrumentation-pika/tests/test_pika_instrumentation.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
from wrapt import BoundFunctionWrapper
1919

2020
from opentelemetry.instrumentation.pika import PikaInstrumentor
21+
from opentelemetry.instrumentation.pika.pika_instrumentor import (
22+
_consumer_callback_attribute_name,
23+
)
2124
from opentelemetry.instrumentation.pika.utils import dummy_callback
2225
from opentelemetry.trace import Tracer
2326

@@ -26,7 +29,8 @@ class TestPika(TestCase):
2629
def setUp(self) -> None:
2730
self.channel = mock.MagicMock(spec=Channel)
2831
consumer_info = mock.MagicMock()
29-
consumer_info.on_message_callback = mock.MagicMock()
32+
callback_attr = PikaInstrumentor.CONSUMER_CALLBACK_ATTR
33+
setattr(consumer_info, callback_attr, mock.MagicMock())
3034
self.channel._consumer_infos = {"consumer-tag": consumer_info}
3135
self.mock_callback = mock.MagicMock()
3236

@@ -72,8 +76,11 @@ def test_instrument_consumers(
7276
self, decorate_callback: mock.MagicMock
7377
) -> None:
7478
tracer = mock.MagicMock(spec=Tracer)
79+
callback_attr = PikaInstrumentor.CONSUMER_CALLBACK_ATTR
7580
expected_decoration_calls = [
76-
mock.call(value.on_message_callback, tracer, key, dummy_callback)
81+
mock.call(
82+
getattr(value, callback_attr), tracer, key, dummy_callback
83+
)
7784
for key, value in self.channel._consumer_infos.items()
7885
]
7986
PikaInstrumentor._instrument_blocking_channel_consumers(
@@ -109,3 +116,13 @@ def test_uninstrument_channel_functions(self) -> None:
109116
self.channel.basic_publish._original_function = original_function
110117
PikaInstrumentor._uninstrument_channel_functions(self.channel)
111118
self.assertEqual(self.channel.basic_publish, original_function)
119+
120+
def test_consumer_callback_attribute_name(self) -> None:
121+
with mock.patch("pika.__version__", "1.0.0"):
122+
self.assertEqual(
123+
_consumer_callback_attribute_name(), "on_message_callback"
124+
)
125+
with mock.patch("pika.__version__", "0.12.0"):
126+
self.assertEqual(
127+
_consumer_callback_attribute_name(), "consumer_cb"
128+
)

Diff for: opentelemetry-instrumentation/src/opentelemetry/instrumentation/bootstrap_gen.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
"instrumentation": "opentelemetry-instrumentation-mysql==0.27b0",
8282
},
8383
"pika": {
84-
"library": "pika >= 1.1.0",
84+
"library": "pika >= 0.12.0",
8585
"instrumentation": "opentelemetry-instrumentation-pika==0.27b0",
8686
},
8787
"psycopg2": {

Diff for: tox.ini

+6-4
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,8 @@ envlist =
182182
pypy3-test-propagator-ot-trace
183183

184184
; opentelemetry-instrumentation-pika
185-
py3{6,7,8,9,10}-test-instrumentation-pika
186-
pypy3-test-instrumentation-pika
185+
py3{6,7,8,9,10}-test-instrumentation-pika{0,1}
186+
pypy3-test-instrumentation-pika{0,1}
187187

188188
lint
189189
docker-tests
@@ -216,6 +216,8 @@ deps =
216216
sqlalchemy11: sqlalchemy>=1.1,<1.2
217217
sqlalchemy14: aiosqlite
218218
sqlalchemy14: sqlalchemy~=1.4
219+
pika0: pika>=0.12.0,<1.0.0
220+
pika1: pika>=1.0.0
219221

220222
; FIXME: add coverage testing
221223
; FIXME: add mypy testing
@@ -249,7 +251,7 @@ changedir =
249251
test-instrumentation-jinja2: instrumentation/opentelemetry-instrumentation-jinja2/tests
250252
test-instrumentation-logging: instrumentation/opentelemetry-instrumentation-logging/tests
251253
test-instrumentation-mysql: instrumentation/opentelemetry-instrumentation-mysql/tests
252-
test-instrumentation-pika: instrumentation/opentelemetry-instrumentation-pika/tests
254+
test-instrumentation-pika{0,1}: instrumentation/opentelemetry-instrumentation-pika/tests
253255
test-instrumentation-psycopg2: instrumentation/opentelemetry-instrumentation-psycopg2/tests
254256
test-instrumentation-pymemcache: instrumentation/opentelemetry-instrumentation-pymemcache/tests
255257
test-instrumentation-pymongo: instrumentation/opentelemetry-instrumentation-pymongo/tests
@@ -286,7 +288,7 @@ commands_pre =
286288

287289
celery: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-celery[test]
288290

289-
pika: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-pika[test]
291+
pika{0,1}: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-pika[test]
290292

291293
grpc: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-grpc[test]
292294

0 commit comments

Comments
 (0)