Mercurial > libervia-backend
diff sat/core/log_config.py @ 2624:56f94936df1e
code style reformatting using black
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 27 Jun 2018 20:14:46 +0200 |
parents | 26edcf3a30eb |
children | e55f871fa9db |
line wrap: on
line diff
--- a/sat/core/log_config.py Wed Jun 27 07:51:29 2018 +0200 +++ b/sat/core/log_config.py Wed Jun 27 20:14:46 2018 +0200 @@ -31,6 +31,7 @@ def __init__(self, *args, **kwargs): super(TwistedLogger, self).__init__(*args, **kwargs) from twisted.python import log as twisted_log + self.twisted_log = twisted_log def out(self, message, level=None): @@ -38,22 +39,30 @@ @param message: formatted message """ - self.twisted_log.msg(message.encode('utf-8', 'ignore'), sat_logged=True, level=level) + self.twisted_log.msg( + message.encode("utf-8", "ignore"), sat_logged=True, level=level + ) class ConfigureBasic(log.ConfigureBase): - def configureColors(self, colors, force_colors, levels_taints_dict): - super(ConfigureBasic, self).configureColors(colors, force_colors, levels_taints_dict) + super(ConfigureBasic, self).configureColors( + colors, force_colors, levels_taints_dict + ) if colors: import sys + try: isatty = sys.stdout.isatty() except AttributeError: isatty = False - if force_colors or isatty: # FIXME: isatty should be tested on each handler, not globaly + if ( + force_colors or isatty + ): # FIXME: isatty should be tested on each handler, not globaly # we need colors - log.Logger.post_treat = lambda logger, level, message: self.ansiColors(level, message) + log.Logger.post_treat = lambda logger, level, message: self.ansiColors( + level, message + ) elif force_colors: raise ValueError("force_colors can't be used if colors is False") @@ -61,30 +70,36 @@ def getProfile(): """Try to find profile value using introspection""" import inspect + stack = inspect.stack() current_path = stack[0][1] for frame_data in stack[:-1]: if frame_data[1] != current_path: - if log.backend == C.LOG_BACKEND_STANDARD and "/logging/__init__.py" in frame_data[1]: + if ( + log.backend == C.LOG_BACKEND_STANDARD + and "/logging/__init__.py" in frame_data[1] + ): continue break frame = frame_data[0] args = inspect.getargvalues(frame) try: - profile = args.locals.get('profile') or args.locals['profile_key'] + profile = args.locals.get("profile") or args.locals["profile_key"] except (TypeError, KeyError): try: try: - profile = args.locals['self'].profile + profile = args.locals["self"].profile except AttributeError: try: - profile = args.locals['self'].parent.profile + profile = args.locals["self"].parent.profile except AttributeError: - profile = args.locals['self'].host.profile # used in quick_frontend for single profile configuration + profile = args.locals[ + "self" + ].host.profile # used in quick_frontend for single profile configuration except Exception: # we can't find profile, we return an empty value - profile = '' + profile = "" return profile @@ -97,16 +112,23 @@ @param observer: original observer to hook @param can_colors: True if observer can display ansi colors """ + def observer_hook(event): """redirect non SàT log to twisted_logger, and add colors when possible""" - if 'sat_logged' in event: # we only want our own logs, other are managed by twistedObserver + if ( + "sat_logged" in event + ): # we only want our own logs, other are managed by twistedObserver # we add colors if possible - if (can_colors and self.LOGGER_CLASS.colors) or self.LOGGER_CLASS.force_colors: - message = event.get('message', tuple()) - level = event.get('level', C.LOG_LVL_INFO) + if ( + can_colors and self.LOGGER_CLASS.colors + ) or self.LOGGER_CLASS.force_colors: + message = event.get("message", tuple()) + level = event.get("level", C.LOG_LVL_INFO) if message: - event['message'] = (self.ansiColors(level, ''.join(message)),) # must be a tuple - observer(event) # we can now call the original observer + event["message"] = ( + self.ansiColors(level, "".join(message)), + ) # must be a tuple + observer(event) # we can now call the original observer return observer_hook @@ -130,7 +152,7 @@ @param observer: observer to hook @return: hooked observer or original one """ - if hasattr(observer, '__self__'): + if hasattr(observer, "__self__"): ori = observer if isinstance(observer.__self__, self.twisted_log.FileLogObserver): observer = self.changeFileLogObserver(observer) @@ -147,12 +169,15 @@ """initialise needed attributes, and install observers hooks""" self.observers = {} from twisted.python import log as twisted_log + self.twisted_log = twisted_log self.log_publisher = twisted_log.msg.__self__ + def addObserverObserver(self_logpub, other): """Install hook so we know when a new observer is added""" other = self.installObserverHook(other) return self_logpub._originalAddObserver(other) + def removeObserverObserver(self_logpub, ori): """removeObserver hook fix @@ -170,11 +195,20 @@ raise ValueError("Unknown observer") # we replace addObserver/removeObserver by our own - twisted_log.LogPublisher._originalAddObserver = twisted_log.LogPublisher.addObserver - twisted_log.LogPublisher._originalRemoveObserver = twisted_log.LogPublisher.removeObserver - import types # see https://stackoverflow.com/a/4267590 (thx Chris Morgan/aaronasterling) - twisted_log.addObserver = types.MethodType(addObserverObserver, self.log_publisher, twisted_log.LogPublisher) - twisted_log.removeObserver = types.MethodType(removeObserverObserver, self.log_publisher, twisted_log.LogPublisher) + twisted_log.LogPublisher._originalAddObserver = ( + twisted_log.LogPublisher.addObserver + ) + twisted_log.LogPublisher._originalRemoveObserver = ( + twisted_log.LogPublisher.removeObserver + ) + import types # see https://stackoverflow.com/a/4267590 (thx Chris Morgan/aaronasterling) + + twisted_log.addObserver = types.MethodType( + addObserverObserver, self.log_publisher, twisted_log.LogPublisher + ) + twisted_log.removeObserver = types.MethodType( + removeObserverObserver, self.log_publisher, twisted_log.LogPublisher + ) # we now change existing observers for idx, observer in enumerate(self.log_publisher.observers): @@ -186,6 +220,7 @@ def configureOutput(self, output): import sys + if output is None: output = C.LOG_OPT_OUTPUT_SEP + C.LOG_OPT_OUTPUT_DEFAULT self.manageOutputs(output) @@ -194,9 +229,11 @@ if C.LOG_OPT_OUTPUT_DEFAULT in log.handlers: # default output is already managed, we just add output to stdout if we are in debug or nodaemon mode if self.backend_data is None: - raise ValueError("You must pass options as backend_data with Twisted backend") + raise ValueError( + "You must pass options as backend_data with Twisted backend" + ) options = self.backend_data - if options.get('nodaemon', False) or options.get('debug', False): + if options.get("nodaemon", False) or options.get("debug", False): addObserver(self.twisted_log.FileLogObserver(sys.stdout).emit) else: # \\default is not in the output, so we remove current observers @@ -208,49 +245,81 @@ if C.LOG_OPT_OUTPUT_FILE in log.handlers: from twisted.python import logfile + for path in log.handlers[C.LOG_OPT_OUTPUT_FILE]: - log_file = sys.stdout if path == '-' else logfile.LogFile.fromFullPath(path) + log_file = ( + sys.stdout if path == "-" else logfile.LogFile.fromFullPath(path) + ) addObserver(self.twisted_log.FileLogObserver(log_file).emit) if C.LOG_OPT_OUTPUT_MEMORY in log.handlers: - raise NotImplementedError("Memory observer is not implemented in Twisted backend") + raise NotImplementedError( + "Memory observer is not implemented in Twisted backend" + ) def configureColors(self, colors, force_colors, levels_taints_dict): - super(ConfigureTwisted, self).configureColors(colors, force_colors, levels_taints_dict) + super(ConfigureTwisted, self).configureColors( + colors, force_colors, levels_taints_dict + ) self.LOGGER_CLASS.colors = colors self.LOGGER_CLASS.force_colors = force_colors if force_colors and not colors: - raise ValueError('colors must be True if force_colors is True') + raise ValueError("colors must be True if force_colors is True") def postTreatment(self): """Install twistedObserver which manage non SàT logs""" + def twistedObserver(event): """Observer which redirect log message not produced by SàT to SàT logging system""" - if not 'sat_logged' in event: + if not "sat_logged" in event: # this log was not produced by SàT from twisted.python import log as twisted_log + text = twisted_log.textFromEventDict(event) if text is None: return twisted_logger = log.getLogger(C.LOG_TWISTED_LOGGER) - log_method = twisted_logger.error if event.get('isError', False) else twisted_logger.info - log_method(text.decode('utf-8')) + log_method = ( + twisted_logger.error + if event.get("isError", False) + else twisted_logger.info + ) + log_method(text.decode("utf-8")) self.log_publisher._originalAddObserver(twistedObserver) class ConfigureStandard(ConfigureBasic): - - def __init__(self, level=None, fmt=None, output=None, logger=None, colors=False, levels_taints_dict=None, force_colors=False, backend_data=None): + def __init__( + self, + level=None, + fmt=None, + output=None, + logger=None, + colors=False, + levels_taints_dict=None, + force_colors=False, + backend_data=None, + ): if fmt is None: fmt = C.LOG_OPT_FORMAT[1] if output is None: output = C.LOG_OPT_OUTPUT[1] - super(ConfigureStandard, self).__init__(level, fmt, output, logger, colors, levels_taints_dict, force_colors, backend_data) + super(ConfigureStandard, self).__init__( + level, + fmt, + output, + logger, + colors, + levels_taints_dict, + force_colors, + backend_data, + ) def preTreatment(self): """We use logging methods directly, instead of using Logger""" import logging + log.getLogger = logging.getLogger log.debug = logging.debug log.info = logging.info @@ -271,7 +340,7 @@ class SatFormatter(logging.Formatter): u"""Formatter which manage SàT specificities""" _format = fmt - _with_profile = '%(profile)s' in fmt + _with_profile = "%(profile)s" in fmt def __init__(self, can_colors=False): super(SatFormatter, self).__init__(self._format) @@ -288,14 +357,14 @@ record.color_start = log.COLOR_START record.color_end = log.COLOR_END else: - record.color_start = record.color_end = '' + record.color_start = record.color_end = "" s = super(SatFormatter, self).format(record) if do_color: s = ConfigureStandard.ansiColors(record.levelname, s) if sys.platform == "android": # FIXME: dirty hack to workaround android encoding issue on log # need to be fixed properly - return s.encode('ascii', 'ignore') + return s.encode("ascii", "ignore") else: return s @@ -308,7 +377,9 @@ self.name_filter = log.FilterName(logger) if logger else None def configureColors(self, colors, force_colors, levels_taints_dict): - super(ConfigureStandard, self).configureColors(colors, force_colors, levels_taints_dict) + super(ConfigureStandard, self).configureColors( + colors, force_colors, levels_taints_dict + ) self.formatterClass.with_colors = colors self.formatterClass.force_colors = force_colors if not colors and force_colors: @@ -323,6 +394,7 @@ def postTreatment(self): import logging + root_logger = logging.getLogger() if len(root_logger.handlers) == 0: for handler, options in log.handlers.items(): @@ -335,14 +407,21 @@ self._addHandler(root_logger, hdlr, can_colors=can_colors) elif handler == C.LOG_OPT_OUTPUT_MEMORY: from logging.handlers import BufferingHandler + class SatMemoryHandler(BufferingHandler): def emit(self, record): super(SatMemoryHandler, self).emit(self.format(record)) + hdlr = SatMemoryHandler(options) - log.handlers[handler] = hdlr # we keep a reference to the handler to read the buffer later + log.handlers[ + handler + ] = ( + hdlr + ) # we keep a reference to the handler to read the buffer later self._addHandler(root_logger, hdlr, can_colors=False) elif handler == C.LOG_OPT_OUTPUT_FILE: import os.path + for path in options: hdlr = logging.FileHandler(os.path.expanduser(path)) self._addHandler(root_logger, hdlr, can_colors=False) @@ -358,13 +437,16 @@ @param size: number of logs to return """ mem_handler = log.handlers[C.LOG_OPT_OUTPUT_MEMORY] - return (log_msg for log_msg in mem_handler.buffer[size if size is None else -size:]) + return ( + log_msg for log_msg in mem_handler.buffer[size if size is None else -size :] + ) log.configure_cls[C.LOG_BACKEND_BASIC] = ConfigureBasic log.configure_cls[C.LOG_BACKEND_TWISTED] = ConfigureTwisted log.configure_cls[C.LOG_BACKEND_STANDARD] = ConfigureStandard + def configure(backend, **options): """Configure logging behaviour @param backend: can be: @@ -375,6 +457,7 @@ """ return log.configure(backend, **options) + def _parseOptions(options): """Parse string options as given in conf or environment variable, and return expected python value @@ -384,11 +467,11 @@ LEVEL = C.LOG_OPT_LEVEL[0] if COLORS in options: - if options[COLORS].lower() in ('1', 'true'): + if options[COLORS].lower() in ("1", "true"): options[COLORS] = True - elif options[COLORS] == 'force': + elif options[COLORS] == "force": options[COLORS] = True - options['force_colors'] = True + options["force_colors"] = True else: options[COLORS] = False if LEVEL in options: @@ -397,6 +480,7 @@ level = C.LOG_LVL_INFO options[LEVEL] = level + def satConfigure(backend=C.LOG_BACKEND_STANDARD, const=None, backend_data=None): """Configure logging system for SàT, can be used by frontends @@ -413,13 +497,18 @@ log.C = const from sat.tools import config import os + log_conf = {} sat_conf = config.parseMainConf() for opt_name, opt_default in C.LOG_OPTIONS(): try: - log_conf[opt_name] = os.environ[''.join((C.ENV_PREFIX, C.LOG_OPT_PREFIX.upper(), opt_name.upper()))] + log_conf[opt_name] = os.environ[ + "".join((C.ENV_PREFIX, C.LOG_OPT_PREFIX.upper(), opt_name.upper())) + ] except KeyError: - log_conf[opt_name] = config.getConfig(sat_conf, C.LOG_OPT_SECTION, C.LOG_OPT_PREFIX + opt_name, opt_default) + log_conf[opt_name] = config.getConfig( + sat_conf, C.LOG_OPT_SECTION, C.LOG_OPT_PREFIX + opt_name, opt_default + ) _parseOptions(log_conf) configure(backend, backend_data=backend_data, **log_conf)