Configure basic logging, and make it possible to log to console.
--log-to-console will output messages at INFO and above to the command-line. This is super-useful when running cloud-init from a terminal, when you don't want to have to dig in a log file. Change-Id: Ieb3db384b73441c19ef463649c94b04ffaac8026
This commit is contained in:
parent
dc3efec379
commit
a51119762c
@ -40,6 +40,7 @@ class _BlatherLoggerAdapter(logging.LoggerAdapter):
|
||||
|
||||
# TODO(harlowja): we should remove when we no longer have to support 2.6...
|
||||
if sys.version_info[0:2] == (2, 6): # pragma: nocover
|
||||
from logutils.dictconfig import dictConfig
|
||||
|
||||
class _FixedBlatherLoggerAdapter(_BlatherLoggerAdapter):
|
||||
"""Ensures isEnabledFor() exists on adapters that are created."""
|
||||
@ -72,6 +73,7 @@ if sys.version_info[0:2] == (2, 6): # pragma: nocover
|
||||
self.lock = None
|
||||
|
||||
else:
|
||||
from logging.config import dictConfig
|
||||
_NullHandler = logging.NullHandler
|
||||
|
||||
|
||||
@ -80,3 +82,32 @@ def getLogger(name=_BASE, extra=None):
|
||||
if not logger.handlers:
|
||||
logger.addHandler(_NullHandler())
|
||||
return _BlatherLoggerAdapter(logger, extra=extra)
|
||||
|
||||
|
||||
def configure_logging(log_to_console=False):
|
||||
logging_config = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'formatters': {
|
||||
'standard': {
|
||||
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'console': {
|
||||
'level': 'INFO',
|
||||
'class': 'logging.StreamHandler',
|
||||
'formatter': 'standard',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'': {
|
||||
'handlers': [],
|
||||
'level': 'DEBUG',
|
||||
'propagate': True,
|
||||
},
|
||||
},
|
||||
}
|
||||
if log_to_console:
|
||||
logging_config['loggers']['']['handlers'].append('console')
|
||||
dictConfig(logging_config)
|
||||
|
@ -6,6 +6,8 @@
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
from cloudinit import logging
|
||||
|
||||
|
||||
def populate_parser(parser, common, subcommands):
|
||||
"""Populate an ArgumentParser with data rather than code
|
||||
@ -48,6 +50,7 @@ def main(args=sys.argv):
|
||||
|
||||
if not hasattr(parsed, 'func'):
|
||||
parser.error('too few arguments')
|
||||
logging.configure_logging(log_to_console=parsed.log_to_console)
|
||||
parsed.func(parsed)
|
||||
return 0
|
||||
|
||||
@ -63,6 +66,7 @@ def unimplemented_subcommand(args):
|
||||
|
||||
|
||||
COMMON_ARGS = [
|
||||
(('--log-to-console',), {'action': 'store_true', 'default': False}),
|
||||
(('--verbose', '-v'), {'action': 'count', 'default': 0}),
|
||||
]
|
||||
|
||||
|
@ -46,3 +46,18 @@ class TestMain(TestCase):
|
||||
self.assertRaises(SystemExit, shell.main, args=['cloud-init'])
|
||||
self.assertIn('cloud-init: error: too few arguments',
|
||||
stderr.getvalue())
|
||||
|
||||
|
||||
class TestLoggingConfiguration(TestCase):
|
||||
|
||||
@mock.patch('cloudinit.shell.sys.stderr', new_callable=six.StringIO)
|
||||
def test_log_to_console(self, stderr):
|
||||
shell.main(args=['cloud-init', '--log-to-console', 'version'])
|
||||
shell.logging.getLogger().info('test log message')
|
||||
self.assertIn('test log message', stderr.getvalue())
|
||||
|
||||
@mock.patch('cloudinit.shell.sys.stderr', new_callable=six.StringIO)
|
||||
def test_log_to_console_not_default(self, stderr):
|
||||
shell.main(args=['cloud-init', 'version'])
|
||||
shell.logging.getLogger().info('test log message')
|
||||
self.assertNotIn('test log message', stderr.getvalue())
|
||||
|
1
tox.ini
1
tox.ini
@ -22,6 +22,7 @@ install_command = pip install {opts} {packages}
|
||||
[testenv:py26]
|
||||
deps = {[testenv]deps}
|
||||
importlib
|
||||
logutils
|
||||
|
||||
[testenv:py27-coverage]
|
||||
commands = {envpython} {toxinidir}/tools/noproxy nosetests --with-coverage --cover-erase --cover-package=cloudinit --cover-min-percentage=90 --cover-html {posargs}
|
||||
|
Loading…
x
Reference in New Issue
Block a user