Gracefully handle errors in logging config files
Fixes bug #1154245 If the parameter to the --log-config option cannot be loaded by the logging.config.fileConfig() function, you get an exception like this raised: NoSectionError: No section: 'formatters' which doesn't do much to help users understand the error. Improve the situation by wrapping the error in a custom exception type giving this: LogConfigError: Error loading logging config /etc/logging.conf: No section: 'formatters' Also add some tests to check we raise this error under the most common failure conditions. Change-Id: I6ad2eb4867213b6356ce43d75da50218d1b498f6
This commit is contained in:
@@ -29,6 +29,7 @@ It also allows setting of formatting information through conf.
|
||||
|
||||
"""
|
||||
|
||||
import ConfigParser
|
||||
import cStringIO
|
||||
import inspect
|
||||
import itertools
|
||||
@@ -323,10 +324,30 @@ def _create_logging_excepthook(product_name):
|
||||
return logging_excepthook
|
||||
|
||||
|
||||
class LogConfigError(Exception):
|
||||
|
||||
message = _('Error loading logging config %(log_config)s: %(err_msg)s')
|
||||
|
||||
def __init__(self, log_config, err_msg):
|
||||
self.log_config = log_config
|
||||
self.err_msg = err_msg
|
||||
|
||||
def __str__(self):
|
||||
return self.message % dict(log_config=self.log_config,
|
||||
err_msg=self.err_msg)
|
||||
|
||||
|
||||
def _load_log_config(log_config):
|
||||
try:
|
||||
logging.config.fileConfig(log_config)
|
||||
except ConfigParser.Error, exc:
|
||||
raise LogConfigError(log_config, str(exc))
|
||||
|
||||
|
||||
def setup(product_name):
|
||||
"""Setup logging."""
|
||||
if CONF.log_config:
|
||||
logging.config.fileConfig(CONF.log_config)
|
||||
_load_log_config(CONF.log_config)
|
||||
else:
|
||||
_setup_logging_from_conf()
|
||||
sys.excepthook = _create_logging_excepthook(product_name)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import cStringIO
|
||||
import logging
|
||||
import os
|
||||
import StringIO
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
@@ -377,3 +379,49 @@ class LogConfigOptsTestCase(test_utils.BaseTestCase):
|
||||
logdir = '/some/other/path/'
|
||||
CONF(['--logdir', logdir])
|
||||
self.assertEquals(CONF.log_dir, logdir)
|
||||
|
||||
|
||||
class LogConfigTestCase(test_utils.BaseTestCase):
|
||||
|
||||
minimal_config = """[loggers]
|
||||
keys=root
|
||||
|
||||
[formatters]
|
||||
keys=
|
||||
|
||||
[handlers]
|
||||
keys=
|
||||
|
||||
[logger_root]
|
||||
handlers=
|
||||
"""
|
||||
|
||||
def _create_tempfile(self, basename, contents, ext='.conf'):
|
||||
(fd, path) = tempfile.mkstemp(prefix=basename, suffix=ext)
|
||||
try:
|
||||
os.write(fd, contents)
|
||||
finally:
|
||||
os.close(fd)
|
||||
return path
|
||||
|
||||
def test_log_config_ok(self):
|
||||
log_config = self._create_tempfile('logging', self.minimal_config)
|
||||
self.config(log_config=log_config)
|
||||
log.setup('test_log_config')
|
||||
|
||||
def test_log_config_not_exist(self):
|
||||
log_config = self._create_tempfile('logging', self.minimal_config)
|
||||
os.remove(log_config)
|
||||
self.config(log_config=log_config)
|
||||
self.assertRaises(log.LogConfigError, log.setup, 'test_log_config')
|
||||
|
||||
def test_log_config_invalid(self):
|
||||
log_config = self._create_tempfile('logging', self.minimal_config[5:])
|
||||
self.config(log_config=log_config)
|
||||
self.assertRaises(log.LogConfigError, log.setup, 'test_log_config')
|
||||
|
||||
def test_log_config_unreadable(self):
|
||||
log_config = self._create_tempfile('logging', self.minimal_config)
|
||||
os.chmod(log_config, 0)
|
||||
self.config(log_config=log_config)
|
||||
self.assertRaises(log.LogConfigError, log.setup, 'test_log_config')
|
||||
|
||||
Reference in New Issue
Block a user