From 641803668ae2f8d0578c3b2bcaed2d41a1f02427 Mon Sep 17 00:00:00 2001 From: Alexis Lee Date: Tue, 8 Dec 2015 15:27:44 +0000 Subject: [PATCH] Allow reload of 'debug' option Ie9e9a895da1a3fc62580c1febb7cd9f965bbc0f5 adds a 'mutate' flag to options. This is the first patch to use this functionality. It marks the 'debug' option as mutable and registers '_mutate_hook' to be called when mutate_config_files runs. Option 'verbose' is deprecated for removal so I see no need to mark it mutable even though it's closely related. Change-Id: I1e7a69de169cc85f4c09954b2f46ce2da7106d90 Depends-On: Ied006631a6edbeeffae485d28eff700b13a626c1 Depends-On: I9bb2ff39dc1ed0a63bd7e7635704b34c53d32d79 --- oslo_log/_options.py | 1 + oslo_log/log.py | 40 +++++++++++++++++++++++++++------ oslo_log/tests/unit/test_log.py | 27 ++++++++++++++++++++++ 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/oslo_log/_options.py b/oslo_log/_options.py index a6ba74f8..aaaf235d 100644 --- a/oslo_log/_options.py +++ b/oslo_log/_options.py @@ -34,6 +34,7 @@ common_cli_opts = [ cfg.BoolOpt('debug', short='d', default=False, + mutable=True, help='If set to true, the logging level will be set to ' 'DEBUG instead of the default INFO level.'), cfg.BoolOpt('verbose', diff --git a/oslo_log/log.py b/oslo_log/log.py index 3d06d205..770bee9b 100644 --- a/oslo_log/log.py +++ b/oslo_log/log.py @@ -219,6 +219,15 @@ def _load_log_config(log_config_append): raise LogConfigError(log_config_append, six.text_type(exc)) +def _mutate_hook(conf, fresh): + """Reconfigures oslo.log according to the mutated options.""" + + # verbose is deprecated, so I didn't make it mutable, so there's no need to + # test for it here. + if (None, 'debug') in fresh: + _refresh_root_level(conf.debug, conf.verbose) + + def register_options(conf): """Register the command line and configuration options used by oslo.log.""" @@ -234,6 +243,8 @@ def register_options(conf): conf.register_opts(_options.log_opts) formatters._store_global_conf(conf) + conf.register_mutate_hook(_mutate_hook) + def setup(conf, product_name, version='unknown'): """Setup logging for the current application.""" @@ -301,6 +312,27 @@ def _find_facility(facility): return getattr(syslog, facility) +def _refresh_root_level(debug, verbose): + """Set the level of the root logger. + + If 'debug' is True, the level will be DEBUG. Otherwise we look at 'verbose' + - if that is True, the level will be INFO. If neither are set, the level + will be WARNING. + + Note the 'verbose' option is deprecated. + + :param debug + :param verbose + """ + log_root = getLogger(None).logger + if debug: + log_root.setLevel(logging.DEBUG) + elif verbose: + log_root.setLevel(logging.INFO) + else: + log_root.setLevel(logging.WARNING) + + def _setup_logging_from_conf(conf, project, version): log_root = getLogger(None).logger @@ -349,13 +381,7 @@ def _setup_logging_from_conf(conf, project, version): version=version, datefmt=datefmt, config=conf)) - - if conf.debug: - log_root.setLevel(logging.DEBUG) - elif conf.verbose: - log_root.setLevel(logging.INFO) - else: - log_root.setLevel(logging.WARNING) + _refresh_root_level(conf.debug, conf.verbose) for pair in conf.default_log_levels: mod, _sep, level_name = pair.partition('=') diff --git a/oslo_log/tests/unit/test_log.py b/oslo_log/tests/unit/test_log.py index 99a26830..77f1c7b3 100644 --- a/oslo_log/tests/unit/test_log.py +++ b/oslo_log/tests/unit/test_log.py @@ -19,6 +19,7 @@ import datetime import logging import os import platform +import shutil import sys try: import syslog @@ -857,6 +858,32 @@ class FastWatchedFileHandlerTestCase(BaseTestCase): self.assertTrue(os.path.exists(log_path)) +class ConfigTestCase(test_base.BaseTestCase): + def test_mutate(self): + conf = cfg.CONF + old_config = ("[DEFAULT]\n" + "debug = false\n") + new_config = ("[DEFAULT]\n" + "debug = true\n") + paths = self.create_tempfiles([('old', old_config), + ('new', new_config)]) + log.register_options(conf) + conf(['--config-file', paths[0]]) + log_root = log.getLogger(None).logger + + log._setup_logging_from_conf(conf, 'test', 'test') + self.assertEqual(conf.debug, False) + self.assertEqual(conf.verbose, True) + self.assertEqual(log.INFO, log_root.getEffectiveLevel()) + + shutil.copy(paths[1], paths[0]) + conf.mutate_config_files() + + self.assertEqual(conf.debug, True) + self.assertEqual(conf.verbose, True) + self.assertEqual(log.DEBUG, log_root.getEffectiveLevel()) + + class LogConfigOptsTestCase(BaseTestCase): def setUp(self):