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 4cfff745d1750..bb20fd5442cf5 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py @@ -71,28 +71,32 @@ def started(self, event: monitoring.CommandStartedEvent): try: span = self._tracer.start_span(name, kind=SpanKind.CLIENT) - span.set_attribute("component", DATABASE_TYPE) - span.set_attribute("db.type", DATABASE_TYPE) - span.set_attribute("db.instance", event.database_name) - span.set_attribute("db.statement", statement) - if event.connection_id is not None: - span.set_attribute("net.peer.name", event.connection_id[0]) - span.set_attribute("net.peer.port", event.connection_id[1]) - - # pymongo specific, not specified by spec - span.set_attribute("db.mongo.operation_id", event.operation_id) - span.set_attribute("db.mongo.request_id", event.request_id) - - for attr in COMMAND_ATTRIBUTES: - _attr = event.command.get(attr) - if _attr is not None: - span.set_attribute("db.mongo." + attr, str(_attr)) + if span.is_recording(): + span.set_attribute("component", DATABASE_TYPE) + span.set_attribute("db.type", DATABASE_TYPE) + span.set_attribute("db.instance", event.database_name) + span.set_attribute("db.statement", statement) + if event.connection_id is not None: + span.set_attribute("net.peer.name", event.connection_id[0]) + span.set_attribute("net.peer.port", event.connection_id[1]) + + # pymongo specific, not specified by spec + span.set_attribute("db.mongo.operation_id", event.operation_id) + span.set_attribute("db.mongo.request_id", event.request_id) + + for attr in COMMAND_ATTRIBUTES: + _attr = event.command.get(attr) + if _attr is not None: + span.set_attribute("db.mongo." + attr, str(_attr)) # Add Span to dictionary self._span_dict[_get_span_dict_key(event)] = span except Exception as ex: # noqa pylint: disable=broad-except if span is not None: - span.set_status(Status(StatusCanonicalCode.INTERNAL, str(ex))) + if span.is_recording(): + span.set_status( + Status(StatusCanonicalCode.INTERNAL, str(ex)) + ) span.end() self._pop_span(event) @@ -103,8 +107,11 @@ def succeeded(self, event: monitoring.CommandSucceededEvent): span = self._pop_span(event) if span is None: return - span.set_attribute("db.mongo.duration_micros", event.duration_micros) - span.set_status(Status(StatusCanonicalCode.OK, event.reply)) + if span.is_recording(): + span.set_attribute( + "db.mongo.duration_micros", event.duration_micros + ) + span.set_status(Status(StatusCanonicalCode.OK, event.reply)) span.end() def failed(self, event: monitoring.CommandFailedEvent): @@ -114,8 +121,11 @@ def failed(self, event: monitoring.CommandFailedEvent): span = self._pop_span(event) if span is None: return - span.set_attribute("db.mongo.duration_micros", event.duration_micros) - span.set_status(Status(StatusCanonicalCode.UNKNOWN, event.failure)) + if span.is_recording(): + span.set_attribute( + "db.mongo.duration_micros", event.duration_micros + ) + span.set_status(Status(StatusCanonicalCode.UNKNOWN, event.failure)) span.end() def _pop_span(self, event): diff --git a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py index a84841b28b28b..d5f67cafe8c74 100644 --- a/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py +++ b/instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py @@ -91,6 +91,22 @@ def test_succeeded(self): self.assertEqual(span.status.description, "reply") self.assertIsNotNone(span.end_time) + def test_not_recording(self): + mock_tracer = mock.Mock() + mock_span = mock.Mock() + mock_span.is_recording.return_value = False + mock_tracer.start_span.return_value = mock_span + mock_tracer.use_span.return_value.__enter__ = mock_span + mock_tracer.use_span.return_value.__exit__ = True + mock_event = MockEvent({}) + command_tracer = CommandTracer(mock_tracer) + command_tracer.started(event=mock_event) + command_tracer.succeeded(event=mock_event) + self.assertFalse(mock_span.is_recording()) + self.assertTrue(mock_span.is_recording.called) + self.assertFalse(mock_span.set_attribute.called) + self.assertFalse(mock_span.set_status.called) + def test_failed(self): mock_event = MockEvent({}) command_tracer = CommandTracer(self.tracer)