Skip to content

Commit cb20aad

Browse files
committed
PYTHON-2533 Add support for sample_rate and filter in set_profiling_level (#605)
(cherry picked from commit a44e719)
1 parent b9cd9c2 commit cb20aad

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

pymongo/database.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,8 @@ def profiling_level(self, session=None):
10861086
assert result["was"] >= 0 and result["was"] <= 2
10871087
return result["was"]
10881088

1089-
def set_profiling_level(self, level, slow_ms=None, session=None):
1089+
def set_profiling_level(self, level, slow_ms=None, session=None,
1090+
sample_rate=None, filter=None):
10901091
"""Set the database's profiling level.
10911092
10921093
:Parameters:
@@ -1097,6 +1098,10 @@ def set_profiling_level(self, level, slow_ms=None, session=None):
10971098
slower than the `slow_ms` level will get written to the logs.
10981099
- `session` (optional): a
10991100
:class:`~pymongo.client_session.ClientSession`.
1101+
- `sample_rate` (optional): The fraction of slow operations that
1102+
should be profiled or logged expressed as a float between 0 and 1.
1103+
- `filter` (optional): A filter expression that controls which
1104+
operations are profiled and logged.
11001105
11011106
Possible `level` values:
11021107
@@ -1114,6 +1119,9 @@ def set_profiling_level(self, level, slow_ms=None, session=None):
11141119
(:data:`~pymongo.OFF`, :data:`~pymongo.SLOW_ONLY`,
11151120
:data:`~pymongo.ALL`).
11161121
1122+
.. versionchanged:: 3.12
1123+
Added the ``sample_rate`` and ``filter`` parameters.
1124+
11171125
.. versionchanged:: 3.6
11181126
Added ``session`` parameter.
11191127
@@ -1125,10 +1133,18 @@ def set_profiling_level(self, level, slow_ms=None, session=None):
11251133
if slow_ms is not None and not isinstance(slow_ms, int):
11261134
raise TypeError("slow_ms must be an integer")
11271135

1136+
if sample_rate is not None and not isinstance(sample_rate, float):
1137+
raise TypeError(
1138+
"sample_rate must be a float, not %r" % (sample_rate,))
1139+
1140+
cmd = SON(profile=level)
11281141
if slow_ms is not None:
1129-
self.command("profile", level, slowms=slow_ms, session=session)
1130-
else:
1131-
self.command("profile", level, session=session)
1142+
cmd['slowms'] = slow_ms
1143+
if sample_rate is not None:
1144+
cmd['sampleRate'] = sample_rate
1145+
if filter is not None:
1146+
cmd['filter'] = filter
1147+
self.command(cmd, session=session)
11321148

11331149
def profiling_info(self, session=None):
11341150
"""Returns a list containing current profiling information.

test/test_database.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,35 @@ def test_profiling_levels(self):
418418
db.set_profiling_level(OFF, 100) # back to default
419419
self.assertEqual(100, db.command("profile", -1)['slowms'])
420420

421+
@client_context.require_no_mongos
422+
@client_context.require_version_min(3, 6)
423+
def test_profiling_sample_rate(self):
424+
db = self.client.pymongo_test
425+
with self.assertRaises(TypeError):
426+
db.set_profiling_level(SLOW_ONLY, 50, sample_rate='1')
427+
with self.assertRaises(TypeError):
428+
db.set_profiling_level(SLOW_ONLY, 50, sample_rate=1)
429+
430+
db.set_profiling_level(SLOW_ONLY, 50, sample_rate=0.0)
431+
db.set_profiling_level(SLOW_ONLY, 50, sample_rate=1.0)
432+
db.set_profiling_level(SLOW_ONLY, 50, sample_rate=0.5)
433+
profile = db.command("profile", -1)
434+
self.assertEqual(50, profile['slowms'])
435+
self.assertEqual(0.5, profile['sampleRate'])
436+
db.set_profiling_level(OFF, 100) # back to default
437+
self.assertEqual(100, db.command("profile", -1)['slowms'])
438+
439+
@client_context.require_no_mongos
440+
@client_context.require_version_min(4, 4, 2)
441+
def test_profiling_filter(self):
442+
db = self.client.pymongo_test
443+
db.set_profiling_level(ALL, filter={'ns': {'$eq': 'test.test'}})
444+
profile = db.command("profile", -1)
445+
self.assertEqual({'ns': {'$eq': 'test.test'}}, profile['filter'])
446+
# filter='unset' resets the filter back to the default.
447+
db.set_profiling_level(OFF, 100, filter='unset')
448+
self.assertEqual(100, db.command("profile", -1)['slowms'])
449+
421450
@client_context.require_no_mongos
422451
def test_profiling_info(self):
423452
db = self.client.pymongo_test

0 commit comments

Comments
 (0)