diff options
| author | Davanum Srinivas <dims@linux.vnet.ibm.com> | 2013-04-04 12:37:17 -0400 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-04-09 23:51:30 +0000 |
| commit | 465e27158725b6b262e251247bc60edaeda2f54d (patch) | |
| tree | ba566f5e248c7bf88b9900b379319e3a957e9a47 | |
| parent | 9dcf688ea80f52cdb5413514198b2aa81d5a4e09 (diff) | |
| download | oslo-465e27158725b6b262e251247bc60edaeda2f54d.tar.gz oslo-465e27158725b6b262e251247bc60edaeda2f54d.tar.xz oslo-465e27158725b6b262e251247bc60edaeda2f54d.zip | |
Support for lazily instantiated loggers
As part of code review for LP #1161031, there was a suggestion
to lazily instantiate the logger in oslo. The use case was when
creating LOG at a module level when we have not yet called
logging.setup, we needed a way to delay creating actual loggers
Added a handlers property in ContextAdapter so the existing testcase
can be used for lazy loggers as well
Change-Id: Iae2e379f8a0d2d38836645e7648294dee97deaaa
| -rw-r--r-- | openstack/common/log.py | 36 | ||||
| -rw-r--r-- | tests/unit/test_log.py | 23 |
2 files changed, 52 insertions, 7 deletions
diff --git a/openstack/common/log.py b/openstack/common/log.py index 8f4db7c..31f35a5 100644 --- a/openstack/common/log.py +++ b/openstack/common/log.py @@ -211,7 +211,27 @@ def _get_log_file_path(binary=None): return '%s.log' % (os.path.join(logdir, binary),) -class ContextAdapter(logging.LoggerAdapter): +class BaseLoggerAdapter(logging.LoggerAdapter): + + def audit(self, msg, *args, **kwargs): + self.log(logging.AUDIT, msg, *args, **kwargs) + + +class LazyAdapter(BaseLoggerAdapter): + def __init__(self, name='unknown', version='unknown'): + self._logger = None + self.extra = {} + self.name = name + self.version = version + + @property + def logger(self): + if not self._logger: + self._logger = getLogger(self.name, self.version) + return self._logger + + +class ContextAdapter(BaseLoggerAdapter): warn = logging.LoggerAdapter.warning def __init__(self, logger, project_name, version_string): @@ -219,8 +239,9 @@ class ContextAdapter(logging.LoggerAdapter): self.project = project_name self.version = version_string - def audit(self, msg, *args, **kwargs): - self.log(logging.AUDIT, msg, *args, **kwargs) + @property + def handlers(self): + return self.logger.handlers def deprecated(self, msg, *args, **kwargs): stdmsg = _("Deprecated: %s") % msg @@ -452,6 +473,15 @@ def getLogger(name='unknown', version='unknown'): return _loggers[name] +def getLazyLogger(name='unknown', version='unknown'): + """ + create a pass-through logger that does not create the real logger + until it is really needed and delegates all calls to the real logger + once it is created + """ + return LazyAdapter(name, version) + + class WritableLogger(object): """A thin wrapper that responds to `write` and logs.""" diff --git a/tests/unit/test_log.py b/tests/unit/test_log.py index 4241e2e..a80b872 100644 --- a/tests/unit/test_log.py +++ b/tests/unit/test_log.py @@ -20,17 +20,20 @@ def _fake_context(): return context.RequestContext(1, 1) -class LoggerTestCase(test_utils.BaseTestCase): +class CommonLoggerTestsMixIn(object): + """These tests are shared between LoggerTestCase and + LazyLoggerTestCase. + """ + def setUp(self): - super(LoggerTestCase, self).setUp() + super(CommonLoggerTestsMixIn, self).setUp() # common context has different fields to the defaults in log.py self.config(logging_context_format_string='%(asctime)s %(levelname)s ' '%(name)s [%(request_id)s ' '%(user)s %(tenant)s] ' '%(message)s') - - self.log = log.getLogger() + self.log = None def test_handlers_have_legacy_formatter(self): formatters = [] @@ -73,6 +76,18 @@ class LoggerTestCase(test_utils.BaseTestCase): self.assertRaises(AttributeError, getattr, log, func) +class LoggerTestCase(CommonLoggerTestsMixIn, test_utils.BaseTestCase): + def setUp(self): + super(LoggerTestCase, self).setUp() + self.log = log.getLogger() + + +class LazyLoggerTestCase(CommonLoggerTestsMixIn, test_utils.BaseTestCase): + def setUp(self): + super(LazyLoggerTestCase, self).setUp() + self.log = log.getLazyLogger() + + class LogHandlerTestCase(test_utils.BaseTestCase): def test_log_path_logdir(self): self.config(log_dir='/some/path', log_file=None) |
