Skip to content

Commit 7c57a73

Browse files
committed
opentelemetry-instrumentation-pymongo: fix invalid mongodb collection attribute type
1 parent bd3c1f2 commit 7c57a73

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def started(self, event: monitoring.CommandStartedEvent):
138138
command_name = event.command_name
139139
span_name = f"{event.database_name}.{command_name}"
140140
statement = self._get_statement_by_command_name(command_name, event)
141-
collection = event.command.get(event.command_name)
141+
collection = _get_command_collection_name(event)
142142

143143
try:
144144
span = self._tracer.start_span(span_name, kind=SpanKind.CLIENT)
@@ -221,6 +221,19 @@ def _get_statement_by_command_name(
221221
return statement
222222

223223

224+
def _get_command_collection_name(event: CommandEvent) -> str | None:
225+
collection_name = event.command.get(event.command_name)
226+
if (
227+
not collection_name
228+
or not isinstance(collection_name, str)
229+
or ".." in collection_name
230+
or collection_name[0] == "."
231+
or collection_name[-1] == "."
232+
):
233+
return None
234+
return collection_name
235+
236+
224237
def _get_span_dict_key(
225238
event: CommandEvent,
226239
) -> int | tuple[int, tuple[str, int | None]]:

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,46 @@ def test_capture_statement_disabled_aggregate(self):
276276
span.attributes[SpanAttributes.DB_STATEMENT], "aggregate"
277277
)
278278

279+
def test_collection_name_attribute(self):
280+
scenarios = [
281+
(
282+
{
283+
"command_name": "find",
284+
"find": "test_collection",
285+
},
286+
"test_collection",
287+
),
288+
({"command_name": "find"}, None),
289+
({"command_name": "find", "find": b'invalid'}, None),
290+
({"command_name": "find", "find": ".invalid"}, None),
291+
({"command_name": "find", "find": "invalid."}, None),
292+
({"command_name": "find", "find": "invalid..invalid"}, None),
293+
]
294+
for command_attrs, expected in scenarios:
295+
with self.subTest(command_attrs=command_attrs, expected=expected):
296+
mock_event = MockEvent(command_attrs)
297+
298+
command_tracer = CommandTracer(
299+
self.tracer, capture_statement=True
300+
)
301+
command_tracer.started(event=mock_event)
302+
command_tracer.succeeded(event=mock_event)
303+
304+
spans_list = self.memory_exporter.get_finished_spans()
305+
306+
self.assertEqual(len(spans_list), 1)
307+
span = spans_list[0]
308+
309+
self.assertEqual(
310+
span.attributes[SpanAttributes.DB_STATEMENT], "find"
311+
)
312+
313+
self.assertEqual(
314+
span.attributes.get(SpanAttributes.DB_MONGODB_COLLECTION),
315+
expected,
316+
)
317+
self.memory_exporter.clear()
318+
279319

280320
class MockCommand:
281321
def __init__(self, command_attrs):

0 commit comments

Comments
 (0)