"""Error log.""" import inspect from src.configs import sns as sns_config from src.connectors import logging from src.connectors import sns from src.constants import common_errors def _get_partial_args(func): """Get args and kwargs from partial functions. Args: func (function): function referance Returns: tuple: 0 - args (tuple), 1 - kwargs (dict) """ f = func args = () kwargs = {} while f: args = getattr(f, 'args', ()) + args kwargs.update(getattr(f, 'keywords', {})) f = getattr(f, 'func', None) return args, kwargs def _process_arguments(func_args, *args, **kwargs): """Convert function call args and definition to str. Args: func_args (list): function definition arguments args (tuple): call args values kwargs (dict): call kwargs values Returns: list: of str, call args with param names """ filters = [] last_pos = 0 args_name = '' for arg in func_args: # get arg name if arg.kind == arg.VAR_POSITIONAL: args_name = arg.name # skip if args or kwargs if arg.kind != arg.POSITIONAL_OR_KEYWORD: continue # get arg value from args or kwargs if arg.name in kwargs: value = kwargs[arg.name] del kwargs[arg.name] else: value = args[last_pos] if last_pos < len(args) else None last_pos += 1 filters.append('{}={}'.format(arg.name, value)) # if we have extra args if last_pos < len(args): filters.append('{}=({})'.format(args_name, ','.join(args[last_pos:]))) # process kwargs filters.extend( sorted( ['{}={}'.format(key, value) for key, value in kwargs.items()])) return filters def _get_function_call_description(func, *args, **kwargs): """Get function name and args with values to log errors. Args: func (function): function ref args (tuple): function args values kwargs (dict): function kwargs values Returns: tuple: function name (str) and args with values (str) """ partial_args, partial_kwargs = _get_partial_args(func) args = partial_args + args kwargs.update(partial_kwargs) arguments = list(inspect.signature(func).parameters.values()) filters = _process_arguments(arguments, *args, **kwargs) return func.__name__, ','.join(filters) def _log_message(message): """Log error message. Args: message (str): error message """ logging.logger.error(message) if sns_config.SNS_TARGET_ARN: sns.client.publish( TargetArn=sns_config.SNS_TARGET_ARN, Message=message) def log_missing_records(func, records): """Log function name and records keys that were not found. Args: func (function): Function that did not return expected records. records (list): A list of missing records keys. """ name = func.__name__.replace('get_', '') message = common_errors.RECORDS_NOT_FOUND.format(name, records) _log_message(message) def log_error_by_func(message, func, *args, **kwargs): """Log error message with func description. Args: message (str): error message func (function): function ref args (tuple): function args values kwargs (dict): function kwargs values """ name, arguments = _get_function_call_description(func, *args, **kwargs) _log_message( common_errors.COMMON_FUNCTION_ERROR.format(message, name, arguments))