a new way to configure colors
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/1c074676 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/1c074676 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/1c074676 Branch: refs/heads/ARIA-146-Support-colorful-execution-logging Commit: 1c074676bed7cc31fb11e83a9d6ccf5e8e461283 Parents: 0d5ff7f Author: max-orlov <[email protected]> Authored: Mon Apr 24 13:54:36 2017 +0300 Committer: max-orlov <[email protected]> Committed: Mon Apr 24 13:54:36 2017 +0300 ---------------------------------------------------------------------- aria/cli/color.py | 43 +++++++- aria/cli/commands/executions.py | 8 +- aria/cli/execution_logging.py | 103 ++++++++++++------- aria/core.py | 4 +- aria/orchestrator/context/operation.py | 8 +- .../execution_plugin/ssh/operations.py | 5 + 6 files changed, 117 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/cli/color.py ---------------------------------------------------------------------- diff --git a/aria/cli/color.py b/aria/cli/color.py index a5ed9b7..006af4d 100644 --- a/aria/cli/color.py +++ b/aria/cli/color.py @@ -15,9 +15,9 @@ from StringIO import StringIO import colorama +from jinja2.environment import Template - -class StyledString(object): +class StyledString1(object): FORE = colorama.Fore BACK = colorama.Back @@ -25,9 +25,9 @@ class StyledString(object): def __init__(self, str_to_stylize, *style_args): """ - - :param str_to_stylize: - :param style_args: + + :param str_to_stylize: + :param style_args: :param kwargs: to_close: specifies if end the format on the current line. default to True """ @@ -58,3 +58,36 @@ class StyledString(object): def _is_valid(self, value): return any(value in vars(type).values() for type in (self.FORE, self.BACK, self.STYLE)) + + +# print StyledString1('aaa', StyledString1.FORE.WHITE, StyledString1.FORE.BLACK) + + +class StyledString2(object): + FORE = colorama.Fore + BACK = colorama.Back + STYLE = colorama.Style + + def __init__(self, str_to_stylize): + """ + + :param str_to_stylize: + :param style_args: + :param kwargs: + to_close: specifies if end the format on the current line. default to True + """ + colorama.init() + self._original_str = str_to_stylize + str_template = Template(self._original_str) + self._stylized_str = str_template.render(FORE=self.FORE, BACK=self.BACK, STYLE=self.STYLE) + + def __str__(self): + return self._stylized_str + + def __add__(self, other): + return str(self) + other + + def __radd__(self, other): + return other + str(self) + +# print str(StyledString2('{BACK.RED}123{BACK.BLUE}aaa{STYLE.RESET_ALL}')) + 'bbb' \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/cli/commands/executions.py ---------------------------------------------------------------------- diff --git a/aria/cli/commands/executions.py b/aria/cli/commands/executions.py index a156c3f..6269d28 100644 --- a/aria/cli/commands/executions.py +++ b/aria/cli/commands/executions.py @@ -166,13 +166,9 @@ def start(workflow_name, execution_thread.raise_error_if_exists() execution = workflow_runner.execution - status_msg = 'Execution has ended with "{0}" status'.format(execution.status) - status_msg = color.StyledString(status_msg, color.StyledString.FORE.RED) - logger.info(status_msg) + logger.info('Execution has ended with "{0}" status'.format(execution.status)) if execution.status == Execution.FAILED and execution.error: - error_msg = color.StyledString('Execution error:{0}{1}'.format(os.linesep, execution.error), - color.StyledString.FORE.RED) - logger.info(error_msg) + logger.info('Execution error:{0}{1}'.format(os.linesep, execution.error)) if dry: # remove traces of the dry execution (including tasks, logs, inputs..) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/cli/execution_logging.py ---------------------------------------------------------------------- diff --git a/aria/cli/execution_logging.py b/aria/cli/execution_logging.py index d8f1d59..304da6f 100644 --- a/aria/cli/execution_logging.py +++ b/aria/cli/execution_logging.py @@ -18,7 +18,7 @@ from StringIO import StringIO from contextlib import contextmanager from functools import partial -from .color import StyledString +from .color import StyledString2 from . import logger from .env import env @@ -30,6 +30,16 @@ IMPLEMENTATION = 'implementation' INPUTS = 'inputs' TRACEBACK = 'traceback' MARKER = 'marker' +FINAL_STATES = 'final_states' +SUCCESS_STATE = 'success' +CANCEL_STATE = 'cancel' +FAIL_STATE = 'fail' + + +EXECUTION_BASE_PATTERN = "\'.*\' workflow execution " +SUCCESSFUL_EXECUTION_PATTERN = EXECUTION_BASE_PATTERN + "succeeded" +FAILED_EXECUTION_PATTERN = EXECUTION_BASE_PATTERN + "failed" +CANCELED_EXECUTION_PATTERN = EXECUTION_BASE_PATTERN + "canceled" DEFAULT_FORMATTING = { logger.NO_VERBOSE: {'message': '{message}'}, @@ -52,35 +62,47 @@ DEFAULT_FORMATTING = { DEFAULT_STYLING = { LEVEL: { - 'info': (StyledString.FORE.LIGHTMAGENTA_EX,), - 'debug': (StyledString.FORE.LIGHTMAGENTA_EX, StyledString.STYLE.DIM), - 'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT) + 'info': '{{ FORE.LIGHTMAGENTA_EX }}', + 'debug': '{{ FORE.LIGHTMAGENTA_EX}{STYLE.DIM }}', + 'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}' }, TIMESTAMP: { - 'info': (StyledString.FORE.LIGHTMAGENTA_EX,), - 'debug': (StyledString.FORE.LIGHTMAGENTA_EX, StyledString.STYLE.DIM), - 'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT) + 'info': '{{ FORE.LIGHTMAGENTA_EX }}', + 'debug': '{{ FORE.LIGHTMAGENTA_EX }}{{ STYLE.DIM }}', + 'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}' }, MESSAGE: { - 'info': (StyledString.FORE.LIGHTBLUE_EX,), - 'debug': (StyledString.FORE.LIGHTBLUE_EX, StyledString.STYLE.DIM), - 'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT), + 'info': '{{ FORE.LIGHTBLUE_EX }}', + 'debug': '{{ FORE.LIGHTBLUE_EX }}{{ STYLE.DIM }}', + 'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}' }, IMPLEMENTATION: { - 'info': (StyledString.FORE.LIGHTBLACK_EX,), - 'debug': (StyledString.FORE.LIGHTBLACK_EX, StyledString.STYLE.DIM,), - 'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT,), + 'info': '{{ FORE.LIGHTBLACK_EX }}', + 'debug': '{{ FORE.LIGHTBLACK_EX }}{{ STYLE.DIM }}', + 'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}' }, INPUTS: { - 'info': (StyledString.FORE.BLUE,), - 'debug': (StyledString.FORE.BLUE, StyledString.STYLE.DIM), - 'error': (StyledString.FORE.RED, StyledString.STYLE.BRIGHT,), + 'info': '{{ FORE.BLUE }}', + 'debug': '{{ FORE.BLUE }}{{ STYLE.DIM }}', + 'error': '{{ FORE.RED }}{{ STYLE.BRIGHT }}', }, TRACEBACK: { - 'error': (StyledString.FORE.RED, ) + 'error': '{{ FORE.RED }}' }, - MARKER: StyledString.BACK.LIGHTYELLOW_EX + MARKER: '{{ BACK.LIGHTYELLOW_EX }}', + FINAL_STATES: { + SUCCESS_STATE: '{{ FORE.GREEN }}', + CANCEL_STATE: '{{ FORE.YELLOW }}', + FAIL_STATE: '{{ FORE.RED }}', + } +} + +_PATTERNS = { + SUCCESS_STATE: re.compile(SUCCESSFUL_EXECUTION_PATTERN), + CANCEL_STATE: re.compile(CANCELED_EXECUTION_PATTERN), + FAIL_STATE: re.compile(FAILED_EXECUTION_PATTERN) + } @@ -97,29 +119,34 @@ class _StylizedLogs(object): self._mark_pattern = mark_pattern def __getattr__(self, item): - return partial(self._stylize, style_type=item[1:]) + return partial(self._stylize, msg_type=item[1:]) - def _level(self, level): - return self._stylize(level[0], level, LEVEL) + def _level(self, log_item): + return self._stylize(log_item.level[0], log_item, LEVEL) - def _stylize(self, msg, level, style_type): - return StyledString(msg, *self._styles[style_type].get(level.lower(), [])) + def _stylize(self, msg, log_item, msg_type): + string_marker = (self._final_string_marker(log_item.msg) or + self._styles[msg_type].get(log_item.level.lower(), '')) + return StyledString2( string_marker + str(msg) + '{{ STYLE.RESET_ALL }}') - def _mark(self, str_): - # TODO; this needs more work. since colors cause the patten not to match (since its not a continuous string) + def _markup(self, str_, original_message): if self._mark_pattern is None: return str_ else: regex_pattern = re.compile(self._mark_pattern) - if not re.match(regex_pattern, str_): + if not re.match(regex_pattern, original_message): return str_ marker = self._styles[MARKER] - modified_str = ( + return StyledString2( marker + - str_.replace(StyledString.STYLE.RESET_ALL, StyledString.STYLE.RESET_ALL + marker) + - StyledString.STYLE.RESET_ALL + str_.replace(StyledString2.STYLE.RESET_ALL, '{{ STYLE.RESET_ALL }}' + marker) + + '{{ STYLE.RESET_ALL }}' ) - return modified_str + + def _final_string_marker(self, original_message): + for state, pattern in _PATTERNS.items(): + if re.match(pattern, original_message): + return self._styles[FINAL_STATES][state] def __call__(self, item): # If no formats are passed we revert to the default formats (per level) @@ -129,7 +156,7 @@ class _StylizedLogs(object): formatting_kwargs = dict(item=item) # level - formatting_kwargs['level'] = self._level(item.level) + formatting_kwargs['level'] = self._level(item) # implementation if item.task: @@ -140,28 +167,28 @@ class _StylizedLogs(object): # execution task implementation = item.execution.workflow_name inputs = dict(i.unwrap() for i in item.execution.inputs.values()) + import pydevd; pydevd.settrace('localhost', suspend=False) - formatting_kwargs['implementation'] = self._implementation(implementation, item.level) - formatting_kwargs['inputs'] = self._inputs(inputs, item.level) - + formatting_kwargs['implementation'] = self._implementation(implementation, item) + formatting_kwargs['inputs'] = self._inputs(inputs, item) # timestamp if 'timestamp' in formatting: timestamp = item.created_at.strftime(formatting['timestamp']) else: timestamp = item.created_at - formatting_kwargs['timestamp'] = self._timestamp(timestamp, item.level) + formatting_kwargs['timestamp'] = self._timestamp(timestamp, item) # message - formatting_kwargs['message'] = self._message(item.msg, item.level) + formatting_kwargs['message'] = self._message(item.msg, item) # The message would be marked out if containing the provided pattern - msg.write(self._mark(formatting['message'].format(**formatting_kwargs))) + msg.write(self._markup(formatting['message'].format(**formatting_kwargs), item.msg)) # Add the exception and the error msg. if item.traceback and env.logging.verbosity_level >= logger.MEDIUM_VERBOSE: msg.write(os.linesep) for line in item.traceback.splitlines(True): - msg.write(self._traceback('\t' + '|' + line, item.level)) + msg.write(self._traceback('\t' + '|' + line, item)) return msg.getvalue() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/core.py ---------------------------------------------------------------------- diff --git a/aria/core.py b/aria/core.py index 4e19506..af1984a 100644 --- a/aria/core.py +++ b/aria/core.py @@ -77,8 +77,8 @@ class Core(object): consumption.ConsumerChain( context, ( - # consumption.SatisfyRequirements, - # consumption.ValidateCapabilities, + consumption.SatisfyRequirements, + consumption.ValidateCapabilities, consumption.FindHosts, consumption.ConfigureOperations )).consume() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/orchestrator/context/operation.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/context/operation.py b/aria/orchestrator/context/operation.py index c383958..68a02aa 100644 --- a/aria/orchestrator/context/operation.py +++ b/aria/orchestrator/context/operation.py @@ -30,11 +30,12 @@ class BaseOperationContext(BaseContext): """ def __init__(self, task_id, actor_id, **kwargs): - super(BaseOperationContext, self).__init__(**kwargs) self._task_id = task_id self._actor_id = actor_id self._thread_local = threading.local() - self._register_logger(task_id=self.task.id) + logger_level = kwargs.pop('logger_level', None) + super(BaseOperationContext, self).__init__(**kwargs) + self._register_logger(task_id=self.task.id, level=logger_level) def __repr__(self): details = 'implementation={task.implementation}; ' \ @@ -80,7 +81,8 @@ class BaseOperationContext(BaseContext): 'workdir': self._workdir, 'model_storage': self.model.serialization_dict if self.model else None, 'resource_storage': self.resource.serialization_dict if self.resource else None, - 'execution_id': self._execution_id + 'execution_id': self._execution_id, + 'logger_level': self.logger.level } return { 'context_cls': context_cls, http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/1c074676/aria/orchestrator/execution_plugin/ssh/operations.py ---------------------------------------------------------------------- diff --git a/aria/orchestrator/execution_plugin/ssh/operations.py b/aria/orchestrator/execution_plugin/ssh/operations.py index 7147a30..04ae0ea 100644 --- a/aria/orchestrator/execution_plugin/ssh/operations.py +++ b/aria/orchestrator/execution_plugin/ssh/operations.py @@ -144,6 +144,11 @@ def _fabric_env(ctx, fabric_env, warn_only): env.update(fabric_env or {}) env.setdefault('warn_only', warn_only) # validations + + env['host_string'] = \ + ctx.model.node_template.get_by_name('virtual_ip').nodes[0].runtime_properties[ + 'floating_ip_address'] + if (not env.get('host_string')) and (ctx.task) and (ctx.task.actor) and (ctx.task.actor.host): env['host_string'] = ctx.task.actor.host.host_address if not env.get('host_string'):
