Merge branch 'evilham-colored-output' into 'master'

[UX] Add option to enable LogLevel-based coloured output.

See merge request ungleich-public/cdist!879
This commit is contained in:
poljakowski 2020-06-01 19:11:58 +02:00
commit 3fc36a67a1
9 changed files with 140 additions and 18 deletions

View File

@ -5,6 +5,7 @@ import logging
import collections
import functools
import cdist.configuration
import cdist.log
import cdist.preos
import cdist.info
@ -88,6 +89,13 @@ def check_lower_bounded_int(value, lower_bound, name):
return val
def colored_output_type(val):
boolean_states = cdist.configuration.ColoredOutputOption.BOOLEAN_STATES
if val not in boolean_states.keys():
raise argparse.ArgumentError()
return boolean_states[val]
def get_parsers():
global parser
@ -125,6 +133,15 @@ def get_parsers():
'value.'),
action='count', default=None)
parser['colored_output'] = argparse.ArgumentParser(add_help=False)
parser['colored_output'].add_argument(
'--colors',
help='Use a colored output for different log levels.'
'It can be a boolean or "auto" (default) which enables this '
'feature if stdout is a tty and disables it otherwise.',
action='store', dest='colored_output', required=False,
type=colored_output_type)
parser['beta'] = argparse.ArgumentParser(add_help=False)
parser['beta'].add_argument(
'-b', '--beta',
@ -283,6 +300,7 @@ def get_parsers():
'host', nargs='*', help='Host(s) to operate on.')
parser['config'] = parser['sub'].add_parser(
'config', parents=[parser['loglevel'], parser['beta'],
parser['colored_output'],
parser['common'],
parser['config_main'],
parser['inventory_common'],
@ -301,6 +319,7 @@ def get_parsers():
parser['add-host'] = parser['invsub'].add_parser(
'add-host', parents=[parser['loglevel'], parser['beta'],
parser['colored_output'],
parser['common'],
parser['inventory_common']])
parser['add-host'].add_argument(
@ -315,6 +334,7 @@ def get_parsers():
parser['add-tag'] = parser['invsub'].add_parser(
'add-tag', parents=[parser['loglevel'], parser['beta'],
parser['colored_output'],
parser['common'],
parser['inventory_common']])
parser['add-tag'].add_argument(
@ -346,6 +366,7 @@ def get_parsers():
parser['del-host'] = parser['invsub'].add_parser(
'del-host', parents=[parser['loglevel'], parser['beta'],
parser['colored_output'],
parser['common'],
parser['inventory_common']])
parser['del-host'].add_argument(
@ -363,6 +384,7 @@ def get_parsers():
parser['del-tag'] = parser['invsub'].add_parser(
'del-tag', parents=[parser['loglevel'], parser['beta'],
parser['colored_output'],
parser['common'],
parser['inventory_common']])
parser['del-tag'].add_argument(
@ -398,6 +420,7 @@ def get_parsers():
parser['list'] = parser['invsub'].add_parser(
'list', parents=[parser['loglevel'], parser['beta'],
parser['colored_output'],
parser['common'],
parser['inventory_common']])
parser['list'].add_argument(
@ -430,7 +453,7 @@ def get_parsers():
# Shell
parser['shell'] = parser['sub'].add_parser(
'shell', parents=[parser['loglevel']])
'shell', parents=[parser['loglevel'], parser['colored_output']])
parser['shell'].add_argument(
'-s', '--shell',
help=('Select shell to use, defaults to current shell. Used shell'
@ -495,9 +518,13 @@ def parse_and_configure(argv, singleton=True):
log = logging.getLogger("cdist")
config = cfg.get_config()
if config.get('GLOBAL', {}).get('colored_output', False):
cdist.log.ColorFormatter.USE_COLORS = True
log.verbose("version %s" % cdist.VERSION)
log.trace('command line args: {}'.format(cfg.command_line_args))
log.trace('configuration: {}'.format(cfg.get_config()))
log.trace('configuration: {}'.format(config))
log.trace('configured args: {}'.format(args))
check_beta(vars(args))

View File

@ -27,6 +27,7 @@ import cdist.argparse
import re
import multiprocessing
import logging
import sys
class Singleton(type):
@ -47,6 +48,7 @@ _VERBOSITY_VALUES = (
_ARCHIVING_VALUES = (
'tar', 'tgz', 'tbz2', 'txz', 'none',
)
_COLORED_OUTPUT_DEFAULT = sys.stdout.isatty()
class OptionBase:
@ -246,9 +248,15 @@ class LogLevelOption(OptionBase):
return VerbosityOption().translate(val)
class ColoredOutputOption(BooleanOption):
BOOLEAN_STATES = dict(configparser.ConfigParser.BOOLEAN_STATES,
auto=_COLORED_OUTPUT_DEFAULT)
_ARG_OPTION_MAPPING = {
'beta': 'beta',
'cache_path_pattern': 'cache_path_pattern',
'colored_output': 'colored_output',
'conf_dir': 'conf_dir',
'manifest': 'init_manifest',
'out_path': 'out_path',
@ -294,6 +302,7 @@ class Configuration(metaclass=Singleton):
'remote_shell': StringOption('remote_shell'),
'cache_path_pattern': StringOption('cache_path_pattern'),
'conf_dir': ConfDirOption(),
'colored_output': ColoredOutputOption('colored_output'),
'init_manifest': StringOption('init_manifest'),
'out_path': StringOption('out_path'),
'remote_out_path': StringOption('remote_out_path'),
@ -319,6 +328,7 @@ class Configuration(metaclass=Singleton):
'CDIST_REMOTE_COPY': 'remote_copy',
'CDIST_INVENTORY_DIR': 'inventory_dir',
'CDIST_CACHE_PATH_PATTERN': 'cache_path_pattern',
'CDIST_COLORED_OUTPUT': 'colored_output',
'__cdist_log_level': 'verbosity',
}
ENV_VAR_BOOLEAN_OPTIONS = ('CDIST_BETA', )
@ -332,6 +342,7 @@ class Configuration(metaclass=Singleton):
}
REQUIRED_DEFAULT_CONFIG_VALUES = {
'GLOBAL': {
'colored_output': _COLORED_OUTPUT_DEFAULT,
'verbosity': 0,
},
}

View File

@ -119,6 +119,7 @@ class Manifest(object):
'__cdist_log_level': util.log_level_env_var_val(self.log),
'__cdist_log_level_name': util.log_level_name_env_var_val(
self.log),
'__cdist_colored_log': str(cdist.log.ColorFormatter.USE_COLORS),
}
if dry_run:

View File

@ -129,6 +129,9 @@ class Emulator(object):
# if invalid __cdist_log_level value
logging.root.setLevel(logging.WARNING)
colored_log = self.env.get('__cdist_colored_log', 'False')
cdist.log.ColorFormatter.USE_COLORS = colored_log == 'True'
self.log = logging.getLogger(self.target_host[0])
def commandline(self):

View File

@ -50,6 +50,30 @@ def _trace(msg, *args, **kwargs):
logging.trace = _trace
class ColorFormatter(logging.Formatter):
USE_COLORS = False
RESET = '\033[0m'
COLOR_MAP = {
'ERROR': '\033[0;31m',
'WARNING': '\033[0;33m',
'INFO': '\033[0;94m',
'VERBOSE': '\033[0;34m',
'DEBUG': '\033[0;90m',
'TRACE': '\033[0;37m',
}
def __init__(self, msg):
super().__init__(msg)
def format(self, record):
msg = super().format(record)
if self.USE_COLORS:
color = self.COLOR_MAP.get(record.levelname)
if color:
msg = color + msg + self.RESET
return msg
class DefaultLog(logging.Logger):
FORMAT = '%(levelname)s: %(message)s'
@ -66,7 +90,7 @@ class DefaultLog(logging.Logger):
super().__init__(name)
self.propagate = False
formatter = logging.Formatter(self.FORMAT)
formatter = ColorFormatter(self.FORMAT)
self.addFilter(self)

View File

@ -28,10 +28,12 @@ import argparse
from cdist import test
import cdist.argparse as cap
import logging
import sys
my_dir = op.abspath(op.dirname(__file__))
fixtures = op.join(my_dir, 'fixtures')
interpolation_config_file = op.join(fixtures, "interpolation-test.cfg")
colored_output_default = sys.stdout.isatty()
def newConfigParser():
@ -153,6 +155,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/bin/sh',
'inventory_dir': '',
'cache_path_pattern': '',
'colored_output': colored_output_default,
'conf_dir': '',
'init_manifest': '',
'out_path': '',
@ -184,6 +187,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/bin/sh',
'inventory_dir': None,
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': None,
'init_manifest': None,
'out_path': None,
@ -390,6 +394,7 @@ class ConfigurationTestCase(test.CdistTestCase):
args = argparse.Namespace()
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'verbosity': 0,
},
}
@ -440,6 +445,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/bin/sh',
'inventory_dir': None,
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': None,
'init_manifest': None,
'out_path': None,
@ -515,6 +521,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/usr/bin/sh',
'inventory_dir': '/var/db/cdist/inventory',
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': ['/opt/cdist', ],
'init_manifest': None,
'out_path': None,
@ -556,6 +563,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/bin/sh',
'inventory_dir': '',
'cache_path_pattern': '',
'colored_output': colored_output_default,
'conf_dir': '',
'init_manifest': '',
'out_path': '',
@ -579,6 +587,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/usr/bin/sh',
'inventory_dir': None,
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': [
'/opt/cdist/conf',
'/usr/local/share/cdist/conf',
@ -623,6 +632,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/bin/sh',
'inventory_dir': '',
'cache_path_pattern': '',
'colored_output': colored_output_default,
'conf_dir': '',
'init_manifest': '',
'out_path': '',
@ -645,6 +655,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'local_shell': '/usr/bin/sh',
'remote_shell': '/usr/bin/sh',
'inventory_dir': '/var/db/cdist/inventory',
'colored_output': colored_output_default,
'conf_dir': '/opt/cdist',
'remote_copy': 'myscp',
'remote_exec': 'myexec',
@ -663,6 +674,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/usr/bin/sh',
'inventory_dir': '/var/db/cdist/inventory',
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': [
'/opt/cdist/conf',
'/usr/local/share/cdist/conf',
@ -694,6 +706,7 @@ class ConfigurationTestCase(test.CdistTestCase):
}
expected_config = {
'GLOBAL': {
'colored_output': colored_output_default,
'verbosity': 0,
},
}
@ -767,6 +780,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/usr/bin/sh',
'inventory_dir': '/opt/sysadmin/cdist/inventory',
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': [
'/opt/cdist/conf',
'/usr/local/share/cdist/conf',
@ -865,6 +879,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/usr/bin/sh',
'inventory_dir': '/var/db/cdist/inventory',
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': [
'/opt/conf/cdist',
],
@ -964,6 +979,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/usr/bin/sh',
'inventory_dir': '/var/db/cdist/inventory',
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': [
'/opt/conf/cdist',
],
@ -1063,6 +1079,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'remote_shell': '/usr/bin/sh',
'inventory_dir': '/var/db/cdist/inventory',
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': [
'/opt/conf/cdist',
],
@ -1095,6 +1112,7 @@ class ConfigurationTestCase(test.CdistTestCase):
'beta': True,
'inventory_dir': '/var/db/cdist/inventory',
'cache_path_pattern': None,
'colored_output': colored_output_default,
'conf_dir': [
'/opt/conf/cdist',
],
@ -1125,6 +1143,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'inventory_dir': None,
'colored_output': colored_output_default,
'conf_dir': None,
'verbosity': 0,
},
@ -1148,6 +1167,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'verbosity': cap.VERBOSE_DEBUG,
},
}
@ -1185,6 +1205,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'save_output_streams': True,
'verbosity': 0,
},
@ -1213,6 +1234,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'save_output_streams': False,
'verbosity': 0,
},
@ -1241,6 +1263,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'save_output_streams': False,
'verbosity': 0,
},
@ -1269,6 +1292,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'save_output_streams': False,
'verbosity': 0,
},
@ -1308,6 +1332,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'timestamp': True,
'verbosity': 0,
},
@ -1336,6 +1361,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'timestamp': True,
'verbosity': 0,
},
@ -1364,6 +1390,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'timestamp': False,
'verbosity': 0,
},
@ -1392,6 +1419,7 @@ class ConfigurationTestCase(test.CdistTestCase):
expected_config_dict = {
'GLOBAL': {
'colored_output': colored_output_default,
'timestamp': False,
'verbosity': 0,
},

View File

@ -13,6 +13,12 @@
# Specify cache path pattern.
# cache_path_pattern = %h
#
# colored_output
# Use a colored output for different log levels.
# It can be a boolean or 'auto' (default) which enables this feature if
# stdout is a tty and disables it otherwise.
# colored_output = auto
#
# conf_dir
# List of configuration directories separated with the character conventionally
# used by the operating system to separate search path components (as in PATH),

View File

@ -344,6 +344,11 @@ CDIST_INVENTORY_DIR
CDIST_BETA
Enable beta functionalities.
CDIST_COLORED_OUTPUT
Use a colored output for different log levels.
It can be a boolean or 'auto' (default) which enables this feature if
stdout is a tty and disables it otherwise.
CDIST_CACHE_PATH_PATTERN
Custom cache path pattern.
eof

View File

@ -15,8 +15,9 @@ SYNOPSIS
cdist banner [-h] [-l LOGLEVEL] [-q] [-v]
cdist config [-h] [-l LOGLEVEL] [-q] [-v] [-b] [-g CONFIG_FILE] [-4]
[-6] [-C CACHE_PATH_PATTERN] [-c CONF_DIR] [-i MANIFEST]
cdist config [-h] [-l LOGLEVEL] [-q] [-v] [-b]
[--colors COLORED_OUTPUT] [-g CONFIG_FILE] [-4] [-6]
[-C CACHE_PATH_PATTERN] [-c CONF_DIR] [-i MANIFEST]
[-j [JOBS]] [-n] [-o OUT_PATH] [-P]
[-R [{tar,tgz,tbz2,txz}]] [-r REMOTE_OUT_PATH]
[--remote-copy REMOTE_COPY] [--remote-exec REMOTE_EXEC]
@ -24,8 +25,9 @@ SYNOPSIS
[-p [HOST_MAX]] [-s] [-t]
[host [host ...]]
cdist install [-h] [-l LOGLEVEL] [-q] [-v] [-b] [-g CONFIG_FILE] [-4]
[-6] [-C CACHE_PATH_PATTERN] [-c CONF_DIR] [-i MANIFEST]
cdist install [-h] [-l LOGLEVEL] [-q] [-v] [-b]
[--colors COLORED_OUTPUT] [-g CONFIG_FILE] [-4] [-6]
[-C CACHE_PATH_PATTERN] [-c CONF_DIR] [-i MANIFEST]
[-j [JOBS]] [-n] [-o OUT_PATH] [-P]
[-R [{tar,tgz,tbz2,txz}]] [-r REMOTE_OUT_PATH]
[--remote-copy REMOTE_COPY] [--remote-exec REMOTE_EXEC]
@ -36,26 +38,29 @@ SYNOPSIS
cdist inventory [-h] {add-host,add-tag,del-host,del-tag,list} ...
cdist inventory add-host [-h] [-l LOGLEVEL] [-q] [-v] [-b]
[-g CONFIG_FILE] [-I INVENTORY_DIR]
[-f HOSTFILE]
[--colors COLORED_OUTPUT] [-g CONFIG_FILE]
[-I INVENTORY_DIR] [-f HOSTFILE]
[host [host ...]]
cdist inventory add-tag [-h] [-l LOGLEVEL] [-q] [-v] [-b]
[-g CONFIG_FILE] [-I INVENTORY_DIR]
[-f HOSTFILE] [-T TAGFILE] [-t TAGLIST]
[--colors COLORED_OUTPUT] [-g CONFIG_FILE]
[-I INVENTORY_DIR] [-f HOSTFILE] [-T TAGFILE]
[-t TAGLIST]
[host [host ...]]
cdist inventory del-host [-h] [-l LOGLEVEL] [-q] [-v] [-b]
[-g CONFIG_FILE] [-I INVENTORY_DIR] [-a]
[-f HOSTFILE]
[--colors COLORED_OUTPUT] [-g CONFIG_FILE]
[-I INVENTORY_DIR] [-a] [-f HOSTFILE]
[host [host ...]]
cdist inventory del-tag [-h] [-l LOGLEVEL] [-q] [-v] [-b]
[-g CONFIG_FILE] [-I INVENTORY_DIR] [-a]
[-f HOSTFILE] [-T TAGFILE] [-t TAGLIST]
[--colors COLORED_OUTPUT] [-g CONFIG_FILE]
[-I INVENTORY_DIR] [-a] [-f HOSTFILE]
[-T TAGFILE] [-t TAGLIST]
[host [host ...]]
cdist inventory list [-h] [-l LOGLEVEL] [-q] [-v] [-b] [-g CONFIG_FILE]
cdist inventory list [-h] [-l LOGLEVEL] [-q] [-v] [-b]
[--colors COLORED_OUTPUT] [-g CONFIG_FILE]
[-I INVENTORY_DIR] [-a] [-f HOSTFILE] [-H] [-t]
[host [host ...]]
@ -84,9 +89,11 @@ SYNOPSIS
[-S SCRIPT] [-s SUITE] [-y REMOTE_COPY]
target_dir
cdist shell [-h] [-l LOGLEVEL] [-q] [-v] [-s SHELL]
cdist shell [-h] [-l LOGLEVEL] [-q] [-v] [--colors COLORED_OUTPUT]
[-s SHELL]
cdist info [-h] [-a] [-c CONF_DIR] [-e] [-F] [-f] [-g CONFIG_FILE] [-t] [pattern]
cdist info [-h] [-a] [-c CONF_DIR] [-e] [-F] [-f] [-g CONFIG_FILE] [-t]
[pattern]
DESCRIPTION
@ -104,6 +111,11 @@ All commands accept the following options:
**-h, --help**
Show the help screen.
**--colors COLORED_OUTPUT**
Use a colored output for different log levels.It can
be a boolean or "auto" (default) which enables this
feature if stdout is a tty and disables it otherwise.
**-l LOGLEVEL, --log-level LOGLEVEL**
Set the specified verbosity level. The levels, in
order from the lowest to the highest, are: ERROR (-1),
@ -893,6 +905,11 @@ CDIST_BETA
CDIST_CACHE_PATH_PATTERN
Custom cache path pattern.
CDIST_COLORED_OUTPUT
Use a colored output for different log levels.
It can be a boolean or 'auto' (default) which enables this feature if
stdout is a tty and disables it otherwise.
CDIST_CONFIG_FILE
Custom configuration file.