Repository: open-telemetry/opentelemetry-python-contrib

Issue:
opentelemetry-instrumentation-pymongo is not checking suppress_information 
**Describe your environment** 
- Python 3.9
- opentelemetry-instrumentation-pymongo==0.23b2

**Steps to reproduce**
A method polls our database waiting for success. We've tried to add suppression for this because we get many 10s of segments for this polling, but spans still get generated.

```
  ctx = set_value("suppress_instrumentation", True)

  with tracer.start_as_current_span("polling", ctx):
      tt = time.time()
      while timeout is None or float(timeout) > time.time() - tt:
          status = cls.status(job_id)
          if not status.is_pending():
              return
          await asyncio.sleep(increment)
```
Invoking `cls.status(job_id)` does a mongo query to determine status.

**What is the expected behavior?**
I expect that the mongo query triggered by the status call doesn't generate a span.

**What is the actual behavior?**
many 10s of spans are included in the output of the instrumentation.

**Additional context**
There's a possibility I'm invoking the code wrong here (I'm new to OpenTelemetry), but the implementation for PyMongo doesn't reference the suppression key like other libraries.



Discussion:

Resolving patch:
diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py
--- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py
+++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py
@@ -41,9 +41,11 @@
 
 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
@@ -57,7 +59,9 @@ 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 +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:
+        if not self.is_enabled or context.get_value(
+            _SUPPRESS_INSTRUMENTATION_KEY
+        ):
             return
         span = self._pop_span(event)
         if span is None:
@@ -101,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:
+        if not self.is_enabled or context.get_value(
+            _SUPPRESS_INSTRUMENTATION_KEY
+        ):
             return
         span = self._pop_span(event)
         if span is None:


Test patch:
diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py
--- a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py
+++ b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py
@@ -14,11 +14,13 @@
 
 from unittest import mock
 
+from opentelemetry import context
 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
 
@@ -90,6 +92,31 @@ 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  # pylint: disable=no-member
+        )
+
     def test_failed(self):
         mock_event = MockEvent({})
         command_tracer = CommandTracer(self.tracer)