Exemplo n.º 1
0
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
Exemplo n.º 2
0
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)
Exemplo n.º 3
0
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))
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
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))
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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)
Exemplo n.º 8
0
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)