From ece1a8c3af69da2d76c9e19dcd298c8c055970cd Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 13 Oct 2021 12:12:32 -0400 Subject: [PATCH 1/5] Implement checking for suppression key Add test for suppression key with pymongo changelog update --- CHANGELOG.md | 3 +++ .../instrumentation/pymongo/__init__.py | 11 +++++--- .../tests/test_pymongo.py | 26 +++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f831617bac..1328e3e38b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - `opentelemetry-instrumentation-jinja2` Allow instrumentation of newer Jinja2 versions. +### Changed +- `opentelemetry-instrumentation-pymongo` Add check for suppression key in PyMongo. + ### Added - `opentelemetry-instrumentation-elasticsearch` Added `response_hook` and `request_hook` callbacks ([#670](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/670)) diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py index 69b26414d8..a4beab0af8 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py @@ -41,14 +41,19 @@ from pymongo import monitoring +from opentelemetry import context + from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.pymongo.package import _instruments from opentelemetry.instrumentation.pymongo.version import __version__ +from opentelemetry.instrumentation.utils import _SUPPRESS_INSTRUMENTATION_KEY + from opentelemetry.semconv.trace import DbSystemValues, SpanAttributes from opentelemetry.trace import SpanKind, get_tracer from opentelemetry.trace.status import Status, StatusCode + class CommandTracer(monitoring.CommandListener): def __init__(self, tracer): self._tracer = tracer @@ -57,7 +62,7 @@ def __init__(self, tracer): def started(self, event: monitoring.CommandStartedEvent): """ Method to handle a pymongo CommandStartedEvent """ - if not self.is_enabled: + if not self.is_enabled or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY): return command = event.command.get(event.command_name, "") name = event.command_name @@ -92,7 +97,7 @@ def started(self, event: monitoring.CommandStartedEvent): def succeeded(self, event: monitoring.CommandSucceededEvent): """ Method to handle a pymongo CommandSucceededEvent """ - if not self.is_enabled: + if not self.is_enabled or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY): return span = self._pop_span(event) if span is None: @@ -101,7 +106,7 @@ def succeeded(self, event: monitoring.CommandSucceededEvent): def failed(self, event: monitoring.CommandFailedEvent): """ Method to handle a pymongo CommandFailedEvent """ - if not self.is_enabled: + if not self.is_enabled or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY): return span = self._pop_span(event) if span is None: diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py index fc12a56963..553a3213d7 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py @@ -15,6 +15,8 @@ from unittest import mock from opentelemetry import trace as trace_api +from opentelemetry import context +from opentelemetry.instrumentation.utils import _SUPPRESS_INSTRUMENTATION_KEY from opentelemetry.instrumentation.pymongo import ( CommandTracer, PymongoInstrumentor, @@ -90,6 +92,30 @@ def test_not_recording(self): self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_status.called) + def test_suppression_key(self): + mock_tracer = mock.Mock() + mock_span = mock.Mock() + mock_span.is_recording.return_value = True + mock_tracer.start_span.return_value = mock_span + mock_event = MockEvent({}) + mock_event.command.get = mock.Mock() + mock_event.command.get.return_value = 'dummy' + + token = context.attach( + context.set_value(_SUPPRESS_INSTRUMENTATION_KEY, True) + ) + + try: + command_tracer = CommandTracer(mock_tracer) + command_tracer.started(event=mock_event) + command_tracer.succeeded(event=mock_event) + finally: + context.detach(token) + + # if suppression key is set, CommandTracer methods return immediately, so command.get is not invoked. + self.assertFalse(mock_event.command.get.called) + + def test_failed(self): mock_event = MockEvent({}) command_tracer = CommandTracer(self.tracer) From 8161c4e40e7671d09e1ce2475b37ee6b169fd9d2 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 13 Oct 2021 12:48:56 -0400 Subject: [PATCH 2/5] Linting --- .../instrumentation/pymongo/__init__.py | 15 +++++++++------ .../tests/test_pymongo.py | 7 +++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py index a4beab0af8..a89747936d 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py @@ -42,18 +42,15 @@ from pymongo import monitoring from opentelemetry import context - from opentelemetry.instrumentation.instrumentor import BaseInstrumentor from opentelemetry.instrumentation.pymongo.package import _instruments from opentelemetry.instrumentation.pymongo.version import __version__ from opentelemetry.instrumentation.utils import _SUPPRESS_INSTRUMENTATION_KEY - from opentelemetry.semconv.trace import DbSystemValues, SpanAttributes from opentelemetry.trace import SpanKind, get_tracer from opentelemetry.trace.status import Status, StatusCode - class CommandTracer(monitoring.CommandListener): def __init__(self, tracer): self._tracer = tracer @@ -62,7 +59,9 @@ def __init__(self, tracer): def started(self, event: monitoring.CommandStartedEvent): """ Method to handle a pymongo CommandStartedEvent """ - if not self.is_enabled or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY): + if not self.is_enabled or context.get_value( + _SUPPRESS_INSTRUMENTATION_KEY + ): return command = event.command.get(event.command_name, "") name = event.command_name @@ -97,7 +96,9 @@ def started(self, event: monitoring.CommandStartedEvent): def succeeded(self, event: monitoring.CommandSucceededEvent): """ Method to handle a pymongo CommandSucceededEvent """ - if not self.is_enabled or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY): + if not self.is_enabled or context.get_value( + _SUPPRESS_INSTRUMENTATION_KEY + ): return span = self._pop_span(event) if span is None: @@ -106,7 +107,9 @@ def succeeded(self, event: monitoring.CommandSucceededEvent): def failed(self, event: monitoring.CommandFailedEvent): """ Method to handle a pymongo CommandFailedEvent """ - if not self.is_enabled or context.get_value(_SUPPRESS_INSTRUMENTATION_KEY): + if not self.is_enabled or context.get_value( + _SUPPRESS_INSTRUMENTATION_KEY + ): return span = self._pop_span(event) if span is None: diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py index 553a3213d7..135a70e1e4 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py @@ -14,13 +14,13 @@ from unittest import mock -from opentelemetry import trace as trace_api from opentelemetry import context -from opentelemetry.instrumentation.utils import _SUPPRESS_INSTRUMENTATION_KEY +from opentelemetry import trace as trace_api from opentelemetry.instrumentation.pymongo import ( CommandTracer, PymongoInstrumentor, ) +from opentelemetry.instrumentation.utils import _SUPPRESS_INSTRUMENTATION_KEY from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.test.test_base import TestBase @@ -99,7 +99,7 @@ def test_suppression_key(self): mock_tracer.start_span.return_value = mock_span mock_event = MockEvent({}) mock_event.command.get = mock.Mock() - mock_event.command.get.return_value = 'dummy' + mock_event.command.get.return_value = "dummy" token = context.attach( context.set_value(_SUPPRESS_INSTRUMENTATION_KEY, True) @@ -115,7 +115,6 @@ def test_suppression_key(self): # if suppression key is set, CommandTracer methods return immediately, so command.get is not invoked. self.assertFalse(mock_event.command.get.called) - def test_failed(self): mock_event = MockEvent({}) command_tracer = CommandTracer(self.tracer) From 92804a842d0a22ce297e3004ee659d7d507554e8 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 13 Oct 2021 12:58:07 -0400 Subject: [PATCH 3/5] pylint --- .../opentelemetry-instrumentation-pymongo/tests/test_pymongo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py index 135a70e1e4..7c9e28d043 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py @@ -113,7 +113,7 @@ def test_suppression_key(self): context.detach(token) # if suppression key is set, CommandTracer methods return immediately, so command.get is not invoked. - self.assertFalse(mock_event.command.get.called) + self.assertFalse(mock_event.command.get.called) # pylint: disable=no-member def test_failed(self): mock_event = MockEvent({}) From 37209896b29139df53c00854abb21992fc4347f0 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 13 Oct 2021 13:15:14 -0400 Subject: [PATCH 4/5] Bad reformat --- .../tests/test_pymongo.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py index 7c9e28d043..ea6f9cc3d0 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py @@ -113,7 +113,9 @@ def test_suppression_key(self): context.detach(token) # if suppression key is set, CommandTracer methods return immediately, so command.get is not invoked. - self.assertFalse(mock_event.command.get.called) # pylint: disable=no-member + self.assertFalse( + mock_event.command.get.called # pylint: disable=no-member + ) def test_failed(self): mock_event = MockEvent({}) From d306bcd3f15e83a5c6dc6943ab15ddd1824406b0 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 14 Oct 2021 15:14:07 -0400 Subject: [PATCH 5/5] Update changelog with PR --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55bf0122e1..4f906df98b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - `opentelemetry-instrumentation-pymongo` Add check for suppression key in PyMongo. +- ([#736](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/736)) ### Added - `opentelemetry-instrumentation-elasticsearch` Added `response_hook` and `request_hook` callbacks