mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-28 20:52:57 +08:00
Bugfix/instrument basic publish in pika (#759)
This commit is contained in:
@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- `opentelemetry-sdk-extension-aws` & `opentelemetry-propagator-aws` Release AWS Python SDK Extension as 2.0.1 and AWS Propagator as 1.0.1
|
||||
([#753](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/753))
|
||||
- `opentelemetry-instrumentation-pika` Add `_decorate_basic_consume` to ensure post instrumentation `basic_consume` calls are also instrumented.
|
||||
([#759](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/759))
|
||||
|
||||
### Fixed
|
||||
|
||||
|
@ -70,6 +70,7 @@ class PikaInstrumentor(BaseInstrumentor): # type: ignore
|
||||
function = getattr(channel, function_name)
|
||||
if hasattr(function, "_original_function"):
|
||||
channel.__setattr__(function_name, function._original_function)
|
||||
unwrap(channel, "basic_consume")
|
||||
|
||||
@staticmethod
|
||||
def instrument_channel(
|
||||
@ -90,6 +91,7 @@ class PikaInstrumentor(BaseInstrumentor): # type: ignore
|
||||
PikaInstrumentor._instrument_consumers(
|
||||
channel._impl._consumers, tracer
|
||||
)
|
||||
PikaInstrumentor._decorate_basic_consume(channel, tracer)
|
||||
PikaInstrumentor._instrument_channel_functions(channel, tracer)
|
||||
|
||||
@staticmethod
|
||||
@ -120,6 +122,33 @@ class PikaInstrumentor(BaseInstrumentor): # type: ignore
|
||||
|
||||
wrapt.wrap_function_wrapper(BlockingConnection, "channel", wrapper)
|
||||
|
||||
@staticmethod
|
||||
def _decorate_basic_consume(channel, tracer: Optional[Tracer]) -> None:
|
||||
def wrapper(wrapped, instance, args, kwargs):
|
||||
if not hasattr(channel, "_impl"):
|
||||
_LOG.error(
|
||||
"Could not find implementation for provided channel!"
|
||||
)
|
||||
return wrapped(*args, **kwargs)
|
||||
current_keys = set(channel._impl._consumers.keys())
|
||||
return_value = wrapped(*args, **kwargs)
|
||||
new_key_list = list(
|
||||
set(channel._impl._consumers.keys()) - current_keys
|
||||
)
|
||||
if not new_key_list:
|
||||
_LOG.error("Could not find added callback")
|
||||
return return_value
|
||||
new_key = new_key_list[0]
|
||||
callback = channel._impl._consumers[new_key]
|
||||
decorated_callback = utils._decorate_callback(
|
||||
callback, tracer, new_key
|
||||
)
|
||||
setattr(decorated_callback, "_original_callback", callback)
|
||||
channel._impl._consumers[new_key] = decorated_callback
|
||||
return return_value
|
||||
|
||||
wrapt.wrap_function_wrapper(channel, "basic_consume", wrapper)
|
||||
|
||||
def _instrument(self, **kwargs: Dict[str, Any]) -> None:
|
||||
tracer_provider: TracerProvider = kwargs.get("tracer_provider", None)
|
||||
self.__setattr__("__opentelemetry_tracer_provider", tracer_provider)
|
||||
|
@ -41,6 +41,8 @@ def _decorate_callback(
|
||||
) -> Any:
|
||||
if not properties:
|
||||
properties = BasicProperties(headers={})
|
||||
if properties.headers is None:
|
||||
properties.headers = {}
|
||||
ctx = propagate.extract(properties.headers, getter=_pika_getter)
|
||||
if not ctx:
|
||||
ctx = context.get_current()
|
||||
@ -74,6 +76,8 @@ def _decorate_basic_publish(
|
||||
) -> Any:
|
||||
if not properties:
|
||||
properties = BasicProperties(headers={})
|
||||
if properties.headers is None:
|
||||
properties.headers = {}
|
||||
ctx = context.get_current()
|
||||
span = _get_span(
|
||||
tracer,
|
||||
|
@ -45,12 +45,16 @@ class TestPika(TestCase):
|
||||
@mock.patch(
|
||||
"opentelemetry.instrumentation.pika.PikaInstrumentor._instrument_channel_functions"
|
||||
)
|
||||
@mock.patch(
|
||||
"opentelemetry.instrumentation.pika.PikaInstrumentor._decorate_basic_consume"
|
||||
)
|
||||
@mock.patch(
|
||||
"opentelemetry.instrumentation.pika.PikaInstrumentor._instrument_consumers"
|
||||
)
|
||||
def test_instrument(
|
||||
self,
|
||||
instrument_consumers: mock.MagicMock,
|
||||
instrument_basic_consume: mock.MagicMock,
|
||||
instrument_channel_functions: mock.MagicMock,
|
||||
):
|
||||
PikaInstrumentor.instrument_channel(channel=self.channel)
|
||||
@ -58,6 +62,7 @@ class TestPika(TestCase):
|
||||
self.channel, "_is_instrumented_by_opentelemetry"
|
||||
), "channel is not marked as instrumented!"
|
||||
instrument_consumers.assert_called_once()
|
||||
instrument_basic_consume.assert_called_once()
|
||||
instrument_channel_functions.assert_called_once()
|
||||
|
||||
@mock.patch("opentelemetry.instrumentation.pika.utils._decorate_callback")
|
||||
|
@ -17,6 +17,7 @@ from typing import Dict, Sequence
|
||||
from wrapt import ObjectProxy
|
||||
|
||||
# pylint: disable=unused-import
|
||||
# pylint: disable=E0611
|
||||
from opentelemetry.context import _SUPPRESS_INSTRUMENTATION_KEY # noqa: F401
|
||||
from opentelemetry.trace import StatusCode
|
||||
|
||||
|
Reference in New Issue
Block a user