From b95ce714dc336bf1a77e17e7f0160120da9e130a Mon Sep 17 00:00:00 2001
From: TerryHowe <terrylhowe@gmail.com>
Date: Tue, 11 Aug 2015 11:30:31 -0600
Subject: [PATCH] Allow custom log levels for other loggers

It would be convenient to be able to enable special logging for
various components that openstack uses.  The biggest thing is
the --debug prints a lot of information when often all I want to
see is the outgoing requests/responses.  To get just that logged
you would put this in your clouds.yaml:

    logging:
        keystoneclient.session: debug

Closes-Bug: #1484660
Change-Id: I15c2607e8262f10903dd831ee8622fb5d6315310
---
 openstackclient/common/logs.py | 46 +++++++++++++++++++++++++++-------
 1 file changed, 37 insertions(+), 9 deletions(-)

diff --git a/openstackclient/common/logs.py b/openstackclient/common/logs.py
index 6d1aec13b7..7ad6e832b9 100644
--- a/openstackclient/common/logs.py
+++ b/openstackclient/common/logs.py
@@ -18,6 +18,13 @@ import sys
 import warnings
 
 
+def get_loggers():
+    loggers = {}
+    for logkey in logging.Logger.manager.loggerDict.keys():
+        loggers[logkey] = logging.getLevelName(logging.getLogger(logkey).level)
+    return loggers
+
+
 def log_level_from_options(options):
     # if --debug, --quiet or --verbose is not specified,
     # the default logging level is warning
@@ -34,6 +41,17 @@ def log_level_from_options(options):
     return log_level
 
 
+def log_level_from_string(level_string):
+    log_level = {
+        'critical': logging.CRITICAL,
+        'error': logging.ERROR,
+        'warning': logging.WARNING,
+        'info': logging.INFO,
+        'debug': logging.DEBUG,
+    }.get(level_string, logging.WARNING)
+    return log_level
+
+
 def log_level_from_config(config):
     # Check the command line option
     verbose_level = config.get('verbose_level')
@@ -49,15 +67,7 @@ def log_level_from_config(config):
         verbose_level = 'info'
     else:
         verbose_level = 'debug'
-
-    log_level = {
-        'critical': logging.CRITICAL,
-        'error': logging.ERROR,
-        'warning': logging.WARNING,
-        'info': logging.INFO,
-        'debug': logging.DEBUG,
-    }.get(verbose_level, logging.WARNING)
-    return log_level
+    return log_level_from_string(verbose_level)
 
 
 def set_warning_filter(log_level):
@@ -168,3 +178,21 @@ class LogConfigurator(object):
             self.file_logger.setFormatter(_FileFormatter(config=cloud_config))
             self.file_logger.setLevel(log_level)
             self.root_logger.addHandler(self.file_logger)
+
+        logconfig = cloud_config.config.get('logging', None)
+        if logconfig:
+            highest_level = logging.NOTSET
+            for k in logconfig.keys():
+                level = log_level_from_string(logconfig[k])
+                logging.getLogger(k).setLevel(level)
+                if (highest_level < level):
+                    highest_level = level
+            self.console_logger.setLevel(highest_level)
+            if self.file_logger:
+                self.file_logger.setLevel(highest_level)
+            # loggers that are not set will use the handler level, so we
+            # need to set the global level for all the loggers
+            for logkey in logging.Logger.manager.loggerDict.keys():
+                logger = logging.getLogger(logkey)
+                if logger.level == logging.NOTSET:
+                    logger.setLevel(log_level)