Merge branch '20613-googleapiclient-init-logs'
[arvados.git] / sdk / python / arvados / api.py
index 2bb60564b7ce13197a2672120830156a532c79ad..a7f3837599c20d82df65a50e6e139d89629f56b5 100644 (file)
@@ -261,13 +261,16 @@ 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_preconfigured = (
-        # "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 not client_logger_preconfigured:
+    if client_logger_unconfigured:
         client_level = client_logger.level
         client_filter = GoogleHTTPClientFilter()
         client_logger.addFilter(client_filter)
@@ -276,18 +279,20 @@ def api_client(
             client_logger.setLevel(client_level)
         else:
             client_logger.setLevel(client_filter.retry_levelno)
-    svc = apiclient_discovery.build(
-        'arvados', version,
-        cache_discovery=False,
-        discoveryServiceUrl=discoveryServiceUrl,
-        http=http,
-        num_retries=num_retries,
-        **kwargs,
-    )
-    if not client_logger_preconfigured:
-        client_logger.removeHandler(log_handler)
-        client_logger.removeFilter(client_filter)
-        client_logger.setLevel(client_level)
+    try:
+        svc = apiclient_discovery.build(
+            'arvados', version,
+            cache_discovery=False,
+            discoveryServiceUrl=discoveryServiceUrl,
+            http=http,
+            num_retries=num_retries,
+            **kwargs,
+        )
+    finally:
+        if client_logger_unconfigured:
+            client_logger.removeHandler(log_handler)
+            client_logger.removeFilter(client_filter)
+            client_logger.setLevel(client_level)
     svc.api_token = token
     svc.insecure = insecure
     svc.request_id = request_id