From c48b9f0eedf34e237fdd4d4017b0b5dd9f96e2a3 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Thu, 7 Aug 2025 10:18:17 -0400 Subject: [PATCH 1/3] PYTHON-5218 - Add logging statement when SRV polling fails --- pymongo/asynchronous/monitor.py | 3 ++- pymongo/synchronous/monitor.py | 3 ++- test/asynchronous/test_srv_polling.py | 14 ++++++++++++++ test/test_srv_polling.py | 14 ++++++++++++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/pymongo/asynchronous/monitor.py b/pymongo/asynchronous/monitor.py index e067bd8c54..45c12b219f 100644 --- a/pymongo/asynchronous/monitor.py +++ b/pymongo/asynchronous/monitor.py @@ -423,12 +423,13 @@ async def _get_seedlist(self) -> Optional[list[tuple[str, Any]]]: if len(seedlist) == 0: # As per the spec: this should be treated as a failure. raise Exception - except Exception: + except Exception as exc: # As per the spec, upon encountering an error: # - An error must not be raised # - SRV records must be rescanned every heartbeatFrequencyMS # - Topology must be left unchanged self.request_check() + _debug_log(_SDAM_LOGGER, message="SRV monitor check failed", failure=repr(exc)) return None else: self._executor.update_interval(max(ttl, common.MIN_SRV_RESCAN_INTERVAL)) diff --git a/pymongo/synchronous/monitor.py b/pymongo/synchronous/monitor.py index d5dd5caf82..f395588814 100644 --- a/pymongo/synchronous/monitor.py +++ b/pymongo/synchronous/monitor.py @@ -421,12 +421,13 @@ def _get_seedlist(self) -> Optional[list[tuple[str, Any]]]: if len(seedlist) == 0: # As per the spec: this should be treated as a failure. raise Exception - except Exception: + except Exception as exc: # As per the spec, upon encountering an error: # - An error must not be raised # - SRV records must be rescanned every heartbeatFrequencyMS # - Topology must be left unchanged self.request_check() + _debug_log(_SDAM_LOGGER, message="SRV monitor check failed", failure=repr(exc)) return None else: self._executor.update_interval(max(ttl, common.MIN_SRV_RESCAN_INTERVAL)) diff --git a/test/asynchronous/test_srv_polling.py b/test/asynchronous/test_srv_polling.py index 18a367a498..23daea8a2a 100644 --- a/test/asynchronous/test_srv_polling.py +++ b/test/asynchronous/test_srv_polling.py @@ -225,6 +225,20 @@ def response_callback(*args): await self.run_scenario(response_callback, False) + async def test_dns_failures_logging(self): + from dns import exception + + with self.assertLogs("pymongo.topology", level="DEBUG") as cm: + + def response_callback(*args): + raise exception.Timeout("DNS Failure!") + + await self.run_scenario(response_callback, False) + + srv_failure_logs = [r for r in cm.records if "SRV monitor check failed" in r.getMessage()] + print(srv_failure_logs) + self.assertEqual(len(srv_failure_logs), 1) + async def test_dns_record_lookup_empty(self): response: list = [] await self.run_scenario(response, False) diff --git a/test/test_srv_polling.py b/test/test_srv_polling.py index 87ab418302..17fae4703d 100644 --- a/test/test_srv_polling.py +++ b/test/test_srv_polling.py @@ -225,6 +225,20 @@ def response_callback(*args): self.run_scenario(response_callback, False) + def test_dns_failures_logging(self): + from dns import exception + + with self.assertLogs("pymongo.topology", level="DEBUG") as cm: + + def response_callback(*args): + raise exception.Timeout("DNS Failure!") + + self.run_scenario(response_callback, False) + + srv_failure_logs = [r for r in cm.records if "SRV monitor check failed" in r.getMessage()] + print(srv_failure_logs) + self.assertEqual(len(srv_failure_logs), 1) + def test_dns_record_lookup_empty(self): response: list = [] self.run_scenario(response, False) From 3b91af75485d14d7395e098b2612ca9e12f8b1a2 Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Thu, 7 Aug 2025 10:32:48 -0400 Subject: [PATCH 2/3] Update test/asynchronous/test_srv_polling.py Co-authored-by: Jib --- test/asynchronous/test_srv_polling.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/asynchronous/test_srv_polling.py b/test/asynchronous/test_srv_polling.py index 23daea8a2a..a89403b473 100644 --- a/test/asynchronous/test_srv_polling.py +++ b/test/asynchronous/test_srv_polling.py @@ -236,7 +236,6 @@ def response_callback(*args): await self.run_scenario(response_callback, False) srv_failure_logs = [r for r in cm.records if "SRV monitor check failed" in r.getMessage()] - print(srv_failure_logs) self.assertEqual(len(srv_failure_logs), 1) async def test_dns_record_lookup_empty(self): From f22792de9ae958d1d0b4e27c1ca3d9c0e28b0ffe Mon Sep 17 00:00:00 2001 From: Noah Stapp Date: Thu, 7 Aug 2025 10:32:53 -0400 Subject: [PATCH 3/3] Update test/test_srv_polling.py Co-authored-by: Jib --- test/test_srv_polling.py | 1 - 1 file changed, 1 deletion(-) diff --git a/test/test_srv_polling.py b/test/test_srv_polling.py index 17fae4703d..09579eda12 100644 --- a/test/test_srv_polling.py +++ b/test/test_srv_polling.py @@ -236,7 +236,6 @@ def response_callback(*args): self.run_scenario(response_callback, False) srv_failure_logs = [r for r in cm.records if "SRV monitor check failed" in r.getMessage()] - print(srv_failure_logs) self.assertEqual(len(srv_failure_logs), 1) def test_dns_record_lookup_empty(self):