Skip to content

Commit c9fad50

Browse files
committed
fix: Invalid type in attribute sequence when using sessions
fixes open-telemetry#1918 closes open-telemetry#2010
1 parent 487e811 commit c9fad50

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

instrumentation/opentelemetry-instrumentation-pymongo/src/opentelemetry/instrumentation/pymongo/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def started(self, event: monitoring.CommandStartedEvent):
152152
SpanAttributes.DB_STATEMENT,
153153
_get_statement(event),
154154
)
155-
if collection:
155+
if collection and isinstance(collection, str):
156156
span.set_attribute(
157157
SpanAttributes.DB_MONGODB_COLLECTION, collection
158158
)
@@ -219,7 +219,7 @@ def _get_span_name(event: CommandEvent) -> str:
219219
"""Get the span name for a given pymongo event."""
220220
command_name = event.command_name
221221
collection = event.command.get(command_name)
222-
if collection:
222+
if collection and isinstance(collection, str):
223223
return f"{event.database_name}.{collection}.{command_name}"
224224
return f"{event.database_name}.{command_name}"
225225

instrumentation/opentelemetry-instrumentation-pymongo/tests/test_pymongo.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,31 @@ def test_capture_statement_disabled_aggregate(self):
287287

288288
self.assertNotIn(SpanAttributes.DB_STATEMENT, span.attributes)
289289

290+
def test_endsessions_command_with_dict_list_collection(self):
291+
# Test for https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1918
292+
# endSessions command has a list of dictionaries as collection value
293+
command_attrs = {
294+
"command_name": "endSessions",
295+
"endSessions": [
296+
{"id": {"id": "session1"}},
297+
{"id": {"id": "session2"}},
298+
],
299+
}
300+
command_tracer = CommandTracer(self.tracer)
301+
mock_event = MockEvent(command_attrs)
302+
command_tracer.started(event=mock_event)
303+
command_tracer.succeeded(event=mock_event)
304+
305+
spans_list = self.memory_exporter.get_finished_spans()
306+
self.assertEqual(len(spans_list), 1)
307+
span = spans_list[0]
308+
309+
# Should not have DB_MONGODB_COLLECTION attribute since collection is not a string
310+
self.assertNotIn(SpanAttributes.DB_MONGODB_COLLECTION, span.attributes)
311+
self.assertEqual(span.attributes[SpanAttributes.DB_OPERATION], "endSessions")
312+
# Span name should not include collection name
313+
self.assertEqual(span.name, "database_name.endSessions")
314+
290315

291316
class MockCommand:
292317
def __init__(self, command_attrs):

tests/opentelemetry-docker-tests/tests/pymongo/test_pymongo_functional.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,34 @@ def test_uninstrument(self):
163163
self._collection.find_one()
164164
spans = self.memory_exporter.get_finished_spans()
165165
self.assertEqual(len(spans), 1)
166+
167+
def test_session_end_no_error(self):
168+
"""Test that endSessions doesn't cause instrumentation errors (issue #1918)"""
169+
client = MongoClient(
170+
MONGODB_HOST, MONGODB_PORT, serverSelectionTimeoutMS=2000
171+
)
172+
173+
with self._tracer.start_as_current_span("rootSpan"):
174+
session = client.start_session()
175+
db = client[MONGODB_DB_NAME]
176+
collection = db[MONGODB_COLLECTION_NAME]
177+
# Do a simple operation within the session
178+
collection.find_one({"test": "123"})
179+
# End the session - this should not cause an error
180+
session.end_session()
181+
182+
# Verify spans were created without errors
183+
spans = self.memory_exporter.get_finished_spans()
184+
# Should have at least the find and endSessions operations
185+
self.assertGreaterEqual(len(spans), 2)
186+
187+
session_end_spans = [s for s in spans if s.attributes.get(SpanAttributes.DB_OPERATION) == "endSessions"]
188+
if session_end_spans:
189+
span = session_end_spans[0]
190+
# Should not have DB_MONGODB_COLLECTION attribute since endSessions collection is not a string
191+
self.assertNotIn(SpanAttributes.DB_MONGODB_COLLECTION, span.attributes)
192+
# Should have other expected attributes
193+
self.assertEqual(span.attributes[SpanAttributes.DB_OPERATION], "endSessions")
194+
self.assertEqual(span.attributes[SpanAttributes.DB_NAME], MONGODB_DB_NAME)
195+
196+
client.close()

0 commit comments

Comments
 (0)