def get_colorlog_handler(short=False): # Short log format is for use under systemd. # Here we exclude some info, because they will be added by journalctl. if short: log_format = '%(log_color)s%(levelname)s:%(reset)s %(message)s' else: log_format = '%(log_color)s%(asctime)s %(levelname)s:%(name)s:%(reset)s %(message)s' handler = colorlog.StreamHandler() handler.setFormatter(colorlog.TTYColoredFormatter(log_format, stream=sys.stderr, datefmt='%Y-%m-%d %H:%M:%S')) return handler
def setup_logging(level): handler = colorlog.StreamHandler() handler.setFormatter(colorlog.TTYColoredFormatter( stream=sys.stderr, fmt='%(log_color)s%(levelname)-8s: %(message)s' #' [%(name)s]' )) root = colorlog.getLogger() root.addHandler(handler) root.setLevel(level)
def init_logging(logfile: Optional[str], level: str, no_color: bool = False): handlers = [] if no_color: console = logging.StreamHandler(stream=sys.stderr) console.setFormatter(logging.Formatter('%(levelname)8s: %(message)s')) else: console = colorlog.StreamHandler(stream=sys.stderr) console.setFormatter( colorlog.TTYColoredFormatter( '%(log_color)s%(levelname)8s: %(message)s', stream=sys.stderr)) console.setLevel(level) handlers.append(console) if logfile is not None: logfile_handler = WatchedFileHandler(logfile) # Always log at least at level INFO logfile_handler.setLevel(min(logging.getLevelName(level), logging.INFO)) # type: ignore logfile_handler.setFormatter( logging.Formatter( '%(asctime)s %(process)d/%(threadName)s %(filename)s:%(lineno)d %(levelname)s %(message)s' )) handlers.append( logfile_handler ) # type: ignore # Expects StreamHandler and not WatchedFileHandler, but works... logging.basicConfig(handlers=handlers, level=logging.DEBUG) # silence alembic logging.getLogger('alembic').setLevel(logging.WARN) # silence boto3 # See https://github.com/boto/boto3/issues/521 logging.getLogger('boto3').setLevel(logging.WARN) logging.getLogger('botocore').setLevel(logging.WARN) logging.getLogger('nose').setLevel(logging.WARN) # silence b2 logging.getLogger('b2').setLevel(logging.WARN) # To enable query logging # logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO) logger.info('$ ' + ' '.join(sys.argv))
def _configure_logger(logger_name, stream_format, file_format, logfile, level, log_colors): logger = logging.getLogger(logger_name) logger.setLevel(level) # Clear any existing handlers logger.handlers = [] if file_format and logfile: file_handler = logging.FileHandler(logfile, mode='a', encoding='utf-8') file_handler.setFormatter(logging.Formatter(file_format)) logger.addHandler(file_handler) if stream_format: formatter = colorlog.TTYColoredFormatter(fmt=stream_format, log_colors=log_colors) stream_handler = logging.StreamHandler(stream=sys.stdout) stream_handler.setFormatter(formatter) logger.addHandler(stream_handler)
def init_logging(logfile, console_level, no_color=False): handlers = [] if no_color: console = logging.StreamHandler(sys.stderr) console.setFormatter(logging.Formatter('%(levelname)8s: %(message)s')) else: console = colorlog.StreamHandler(sys.stderr) console.setFormatter( colorlog.TTYColoredFormatter( '%(log_color)s%(levelname)8s: %(message)s')) console.setLevel(console_level) handlers.append(console) if not logfile is None: logfile = WatchedFileHandler(logfile) logfile.setLevel(logging.INFO) logfile.setFormatter( logging.Formatter('%(asctime)s [%(process)d] %(message)s')) handlers.append(logfile) logging.basicConfig(handlers=handlers, level=logging.DEBUG) # silence alembic logging.getLogger('alembic').setLevel(logging.WARN) # silence filelock logging.getLogger('filelock').setLevel(logging.WARN) # silence boto3 # See https://github.com/boto/boto3/issues/521 logging.getLogger('boto3').setLevel(logging.WARN) logging.getLogger('botocore').setLevel(logging.WARN) logging.getLogger('nose').setLevel(logging.WARN) # silence b2 logging.getLogger('b2').setLevel(logging.WARN) #logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO) logger.info('$ ' + ' '.join(sys.argv))
def setupLogging(verbosity=1, levels=None, format=None, stream=sys.stdout): if levels is None: levels = [logging.WARNING, logging.INFO, logging.DEBUG] loglevel = levels[verbosity] if verbosity < len(levels) else logging.DEBUG if format is None: if loglevel <= logging.DEBUG: format = "%(log_color)s%(levelname)s%(reset)s : %(filename)s:%(lineno)d: %(message)s" else: format = "%(log_color)s%(levelname)s%(reset)s : %(message)s" colors = colorlog.default_log_colors.copy() colors.update({ 'DEBUG': 'green' }) formatter = colorlog.TTYColoredFormatter(format, log_colors=colors, stream=stream) handler = logging.StreamHandler() handler.setFormatter(formatter) logging.root.addHandler(handler) logger = logging.getLogger("") logger.setLevel(loglevel) return logger
def main(): args = docopt(__doc__) if args['--version']: print(_gen_version()) sys.exit(0) if args['--debug']: args['--verbose'] = True format_color = '%(log_color)s[%(levelname)s] %(name)s%(reset)s: %(message)s' level = logging.DEBUG elif args['--verbose']: format_color = '%(log_color)s%(levelname)s%(reset)s: %(message)s' level = logging.INFO else: format_color = '%(log_color)s%(levelname)s%(reset)s: %(message)s' level = logging.WARNING sys.tracebacklimit = 0 formatter = colorlog.TTYColoredFormatter(fmt=format_color, stream=sys.stdout) handler = logging.StreamHandler() handler.setFormatter(formatter) logging.basicConfig(level=level, handlers=[handler]) _LOGGER.debug('running %s', _gen_version()) opts = _make_opts(args) filter_count = sum(1 for opt in opts if opt in _FILTER_OPTIONS) device_id = None if not args['--device']: selected = list(find_liquidctl_devices(**opts)) else: _LOGGER.warning( '-d/--device is deprecated, prefer --match or other selection options' ) device_id = int(args['--device']) no_filters = { opt: val for opt, val in opts.items() if opt not in _FILTER_OPTIONS } compat = list(find_liquidctl_devices(**no_filters)) if device_id < 0 or device_id >= len(compat): raise SystemExit('Error: device index out of bounds') if filter_count: # check that --device matches other filter criteria matched_devs = [ dev.device for dev in find_liquidctl_devices(**opts) ] if compat[device_id].device not in matched_devs: raise SystemExit( 'Error: device index does not match remaining selection criteria' ) _LOGGER.warning( 'mixing --device <id> with other filters is not recommended; ' 'to disambiguate between results prefer --pick <result>') selected = [compat[device_id]] if args['list']: _list_devices(selected, using_filters=bool(filter_count), device_id=device_id, **opts) return if len(selected) > 1 and not (args['status'] or args['all']): raise SystemExit( 'Error: too many devices, filter or select one (see: liquidctl --help)' ) elif len(selected) == 0: raise SystemExit( 'Error: no devices matches available drivers and selection criteria' ) errors = 0 def log_error(err, msg, append_err=False, *args): nonlocal errors errors += 1 _LOGGER.info('%s', err, exc_info=True) if append_err: exception = list(format_exception(Exception, err, None))[-1].rstrip() _LOGGER.error(f'{msg}: {exception}', *args) else: _LOGGER.error(msg, *args) for dev in selected: _LOGGER.debug('device: %s', dev.description) try: with dev.connect(**opts): if args['initialize']: _print_dev_status(dev, dev.initialize(**opts)) elif args['status']: _print_dev_status(dev, dev.get_status(**opts)) elif args['set'] and args['speed']: _device_set_speed(dev, args, **opts) elif args['set'] and args['color']: _device_set_color(dev, args, **opts) else: assert False, 'unreachable' except OSError as err: # each backend API returns a different subtype of OSError (OSError, # usb.core.USBError or PermissionError) for permission issues if err.errno in [errno.EACCES, errno.EPERM]: log_error( err, f'Error: insufficient permissions to access {dev.description}' ) elif err.args == ('open failed', ): log_error( err, f'Error: could not open {dev.description}, possibly due to insufficient permissions' ) else: log_error(err, f'Unexpected OS error with {dev.description}', append_err=True) except NotSupportedByDevice as err: log_error(err, f'Error: operation not supported by {dev.description}') except NotSupportedByDriver as err: log_error( err, f'Error: operation not supported by driver for {dev.description}' ) except UnsafeFeaturesNotEnabled as err: features = ','.join(err.args) log_error( err, f'Error: missing --unsafe features for {dev.description}: {features!r}' ) _LOGGER.error( 'More information is provided in the corresponding device guide' ) except Exception as err: log_error(err, f'Unexpected error with {dev.description}', append_err=True) if errors: sys.exit(errors)
def main(): args = docopt(__doc__) if args['--version']: print(_gen_version()) sys.exit(0) if args['--debug']: args['--verbose'] = True log_fmt = '%(log_color)s[%(levelname)s] (%(module)s) (%(funcName)s): %(message)s' log_level = logging.DEBUG elif args['--verbose']: log_fmt = '%(log_color)s%(levelname)s: %(message)s' log_level = logging.INFO else: log_fmt = '%(log_color)s%(levelname)s: %(message)s' log_level = logging.WARNING sys.tracebacklimit = 0 if sys.platform == 'win32': log_colors = { 'DEBUG': f'bold_blue', 'INFO': f'bold_purple', 'WARNING': 'yellow,bold', 'ERROR': 'red,bold', 'CRITICAL': 'red,bold,bg_white', } else: log_colors = { 'DEBUG': f'blue', 'INFO': f'purple', 'WARNING': 'yellow,bold', 'ERROR': 'red,bold', 'CRITICAL': 'red,bold,bg_white', } log_fmtter = colorlog.TTYColoredFormatter(fmt=log_fmt, stream=sys.stderr, log_colors=log_colors) log_handler = logging.StreamHandler() log_handler.setFormatter(log_fmtter) logging.basicConfig(level=log_level, handlers=[log_handler]) _LOGGER.debug('%s', _gen_version()) _LOGGER.debug('platform: %s', platform.platform()) _log_requirements() # unlike humans, machines want to know everything; imply verbose everywhere # other than when setting default logging level and format (which are # inherently for human consumption) if args['--json']: args['--verbose'] = True opts = _make_opts(args) filter_count = sum(1 for opt in opts if opt in _FILTER_OPTIONS) device_id = None if not args['--device']: selected = list(find_liquidctl_devices(**opts)) else: _LOGGER.warning('-d/--device is deprecated, prefer --match or other selection options') device_id = int(args['--device']) no_filters = {opt: val for opt, val in opts.items() if opt not in _FILTER_OPTIONS} compat = list(find_liquidctl_devices(**no_filters)) if device_id < 0 or device_id >= len(compat): raise SystemExit('Error: device index out of bounds') if filter_count: # check that --device matches other filter criteria matched_devs = [dev.device for dev in find_liquidctl_devices(**opts)] if compat[device_id].device not in matched_devs: raise SystemExit('Error: device index does not match remaining selection criteria') _LOGGER.warning('mixing --device <id> with other filters is not recommended; ' 'to disambiguate between results prefer --pick <result>') selected = [compat[device_id]] if args['list']: if args['--json']: objs = _list_devices_objs(selected) print(json.dumps(objs, ensure_ascii=(os.getenv('LANG', None) == 'C'))) else: _list_devices_human(selected, using_filters=bool(filter_count), device_id=device_id, json=json, **opts) return if len(selected) > 1 and not (args['status'] or args['all']): raise SystemExit('Error: too many devices, filter or select one (see: liquidctl --help)') elif len(selected) == 0: raise SystemExit('Error: no devices matches available drivers and selection criteria') errors = 0 def log_error(err, msg, append_err=False, *args): nonlocal errors errors += 1 _LOGGER.info('%s', err, exc_info=True) if append_err: exception = list(format_exception(Exception, err, None))[-1].rstrip() _LOGGER.error(f'{msg}: {exception}', *args) else: _LOGGER.error(msg, *args) # for json obj_buf = [] for dev in selected: _LOGGER.debug('device: %s', dev.description) try: with dev.connect(**opts): if args['initialize']: status = dev.initialize(**opts) if args['--json']: obj_buf.append(_dev_status_obj(dev, status)) else: _print_dev_status(dev, status) elif args['status']: status = dev.get_status(**opts) if args['--json']: obj_buf.append(_dev_status_obj(dev, status)) else: _print_dev_status(dev, status) elif args['set'] and args['speed']: _device_set_speed(dev, args, **opts) elif args['set'] and args['color']: _device_set_color(dev, args, **opts) else: assert False, 'unreachable' except OSError as err: # each backend API returns a different subtype of OSError (OSError, # usb.core.USBError or PermissionError) for permission issues if err.errno in [errno.EACCES, errno.EPERM]: log_error(err, f'Error: insufficient permissions to access {dev.description}') elif err.args == ('open failed', ): log_error(err, f'Error: could not open {dev.description}, possibly due to insufficient permissions') else: log_error(err, f'Unexpected OS error with {dev.description}', append_err=True) except NotSupportedByDevice as err: log_error(err, f'Error: operation not supported by {dev.description}') except NotSupportedByDriver as err: log_error(err, f'Error: operation not supported by driver for {dev.description}') except UnsafeFeaturesNotEnabled as err: features = ','.join(err.args) log_error(err, f'Error: missing --unsafe features for {dev.description}: {features!r}') _LOGGER.error('More information is provided in the corresponding device guide') except Exception as err: log_error(err, f'Unexpected error with {dev.description}', append_err=True) if errors: sys.exit(errors) if args['--json']: # use __str__ for values that cannot be directly serialized to JSON # (e.g. enums) print(json.dumps(obj_buf, ensure_ascii=(os.getenv('LANG', None) == 'C'), default=lambda x: str(x))) sys.exit(0)