From 150de14b0b265d86df11a04201320944d04fe3a5 Mon Sep 17 00:00:00 2001 From: Brett Smith Date: Wed, 7 Jun 2023 15:00:43 -0400 Subject: [PATCH] 20613: Update unconfigured logger check to accommodate NullHandler googleapiclient sets up its own NullHandler, as recommended by the logging documentation. That makes the hasHandlers() test not work as intended, so instead we traverse the hierarchy ourselves looking for a real handler. Arvados-DCO-1.1-Signed-off-by: Brett Smith --- sdk/python/arvados/api.py | 13 ++++++++----- sdk/python/tests/test_api.py | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sdk/python/arvados/api.py b/sdk/python/arvados/api.py index a1493b904e..a7f3837599 100644 --- a/sdk/python/arvados/api.py +++ b/sdk/python/arvados/api.py @@ -261,11 +261,14 @@ def api_client( # can cause clients to appear to hang early. This can be removed after # we have a more general story for handling googleapiclient logs (#20521). client_logger = logging.getLogger('googleapiclient.http') - client_logger_unconfigured = ( - # "first time a client is instantiated" = thread that acquires this lock - # It is never released. - _googleapiclient_log_lock.acquire(blocking=False) - and not client_logger.hasHandlers() + # "first time a client is instantiated" = thread that acquires this lock + # It is never released. + # googleapiclient sets up its own NullHandler so we detect if logging is + # configured by looking for a real handler anywhere in the hierarchy. + client_logger_unconfigured = _googleapiclient_log_lock.acquire(blocking=False) and all( + isinstance(handler, logging.NullHandler) + for logger_name in ['', 'googleapiclient', 'googleapiclient.http'] + for handler in logging.getLogger(logger_name).handlers ) if client_logger_unconfigured: client_level = client_logger.level diff --git a/sdk/python/tests/test_api.py b/sdk/python/tests/test_api.py index 8380185bbb..0f85e5520c 100644 --- a/sdk/python/tests/test_api.py +++ b/sdk/python/tests/test_api.py @@ -402,7 +402,7 @@ class ArvadosApiTest(run_test_server.TestCaseWithServers): pass real_logger = logging.getLogger('googleapiclient.http') mock_logger = mock.Mock(wraps=real_logger) - mock_logger.hasHandlers.return_value = False + mock_logger.handlers = logging.getLogger('googleapiclient').handlers mock_logger.level = logging.NOTSET with mock.patch('logging.getLogger', return_value=mock_logger), \ mock.patch('time.sleep'), \ @@ -421,7 +421,7 @@ class ArvadosApiTest(run_test_server.TestCaseWithServers): def test_configured_logger_untouched(self): real_logger = logging.getLogger('googleapiclient.http') mock_logger = mock.Mock(wraps=real_logger) - mock_logger.hasHandlers.return_value = True + mock_logger.handlers = logging.getLogger().handlers with mock.patch('logging.getLogger', return_value=mock_logger), \ mock.patch('time.sleep'): try: -- 2.30.2