관리-도구
편집 파일: cloudlinux_statistics_parser.py
# coding=utf-8 # # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT import argparse import datetime from typing import Tuple, Iterable # NOQA from lvestats import __version__ from lvestats.lib.parsers.lveinfoargparse import time_unit_type from lvestats.lib.commons.argparse_utils import ParseDatetime, format_aliases, SmartFormatter, BY_USAGE_PERCENT from lvestats.lib.commons.argparse_utils import period_type2, check_percentages, check_positive_int from lvestats.lib.commons.argparse_utils import alias_action, check_from_zero_to_max_int, argparse_process_period BY_FAULT_DSCR = ( ('FIELD', 'DESCRIPTION'), ('any', 'faults of all types'), ('cpu', 'CPU usage faults'), ('io', 'max io usage faults'), ('iops', 'max io operations faults; (LVE version >= 8)'), ('ep', 'max entry processes faults'), ('nproc', 'max processes faults'), ('pmem', 'out of physical memory faults'), ('vmem', 'out of virtual memory faults'), ) BY_USAGE_FIELDS = ( ('FIELD', 'DESCRIPTION'), ('cpu', 'average CPU usage'), ('mysql_cpu', 'average MySQL CPU usage'), ('io', 'average io usage;'), ('mysql_io', 'average MySQL io usage;'), ('iops', 'average io operations; (LVE version >= 8)'), ('ep', 'average number of entry processes (concurrent connections)'), ('nproc', 'average number of processes'), ('pmem', 'average physical memory usage'), ('vmem', 'average virtual memory usage'), ) ORDER_BY_FIELDS = ( ('FIELD', 'DESCRIPTION'), ('any_faults', 'total number of faults of all types'), ('cpu', 'average CPU usage'), ('mysql_cpu', 'average MySQL CPU usage'), ('io', 'average io usage;'), ('mysql_io', 'average MySQL io usage;'), ('iops', 'average io operations; (LVE version >= 8)'), ('ep', 'average number of entry processes (concurrent connections)'), ('nproc', 'average number of processes'), ('pmem', 'average physical memory usage'), ('vmem', 'average virtual memory usage'), ('cpu_faults', 'total number of CPU usage faults'), ('io_faults', 'total number of max io faults'), ('iops_faults', 'total number of max io operations faults; (LVE version >= 8)'), ('ep_faults', 'total number of max entry processes faults'), ('nproc_faults', 'total number of max processes faults'), ('pmem_faults', 'total number of out of physical memory faults'), ('vmem_faults', 'total number of out of virtual memory faults'), ) COLUMNS_DSCR = ( ('Key', 'Fields to show'), ('all', 'all available fields'), ('cpu', 'CPU fields'), ('io', 'IO fields'), ('iops', 'IOPS fields'), ('ep', 'entry processes (concurrent connections) fields'), ('nproc', 'number of processes fields'), ('pmem', 'physical memory fields'), ('vmem', 'virtual memory fields'), ('mysql', 'mysql_cpu & mysql_io fields'), ) def check_argument(value, fields): # type: (str, Iterable[Tuple[str, str]]) -> str value_lowered = value.lower() if value_lowered in list(zip(*fields))[0][1:]: return value_lowered else: raise argparse.ArgumentTypeError( f'"{value}" is an invalid; must be one of the available options: \n{format_aliases(fields)}' ) def check_by_usage(value): # type: (str) -> str return check_argument(value, BY_USAGE_FIELDS) def check_by_fault(value): # type: (str) -> str return check_argument(value, BY_FAULT_DSCR) def check_order_by(value): # type: (str) -> str return check_argument(value, ORDER_BY_FIELDS) def setup_statistics_parser(argv_, server_id='localhost', _datetime_now=None): datetime_now = _datetime_now or datetime.datetime.now() parser = argparse.ArgumentParser( description='%(prog)s - CLI utility that provides historical information ' 'about resource usage of a running system', formatter_class=SmartFormatter, prog='cloudlinux-statistics' ) parser.add_argument( '-j', '--json', help='return data in JSON format', action='store_true') parser.add_argument( '-v', '--version', version=__version__, help='show program\'s version number and exit', action='version') usage_group = parser.add_argument_group('filter items by resource usage') usage_group.add_argument( '--by-usage', type=check_by_usage, help=f'R|show LVEs with usage (averaged) within {BY_USAGE_PERCENT} percent ' f'of the limit available values:\n{format_aliases(BY_USAGE_FIELDS)}') usage_group.add_argument( '--percentage', type=check_percentages, default=BY_USAGE_PERCENT, help='defines percentage for --by-usage option; default %(default)s', metavar='0..100') faults_group = parser.add_argument_group('filter items by amount of faults') faults_group.add_argument( '--by-fault', type=check_by_fault, help=f"R|show only accounts that have some faults for given limit\n{format_aliases(BY_FAULT_DSCR)}") faults_group.add_argument( '--threshold', type=check_positive_int, default=1, help='in combination with --by-fault, shows only accounts with number of faults ' 'more then given; default %(default)s') parser.add_argument( '--server_id', '--server-id', type=str, default=server_id, help='used with central database for multiple servers, default "%(default)s"') # filtering output data group_period = parser.add_argument_group( "filter items by time interval", "get information for given period of time; " "you can either set --from and --to options, " "or just get information for the recent time " "using --period option. --from and --to values " "are ignored when --period is set") group_period.add_argument( '-f', '--from', action=ParseDatetime, default=datetime_now - datetime.timedelta(minutes=10), nargs='+', help='run report from date and time in [YY]YY-MM-DD[ HH:MM] format; ' 'if not present last 10 minutes are assumed') group_period.add_argument( '-t', '--to', action=ParseDatetime, default=datetime_now, nargs='+', help='run report up to date and time in [YY]YY-MM-DD[ HH:MM] format; ' 'if not present, reports results up to now') group_period.add_argument( '--period', type=lambda value: period_type2(value, datetime_now), help='time period; specify minutes with m, h - hours, days with d, and values: today, ' 'yesterday; 5m - last 5 minutes, 4h -- last four hours, 2d - last 2 days, as well as today') parser.add_argument( '--limit', type=check_from_zero_to_max_int, help='limit number of results to display, 0 is unlimited') parser.add_argument( '--show', nargs='+', action=alias_action(COLUMNS_DSCR + (('all', ''),)), default=['all'], help=f'R|show only the listed columns; "all" for all supported columns\n{format_aliases(COLUMNS_DSCR)}', metavar='COLUMN_NAME') parser.add_argument( '-o', '--order-by', type=check_order_by, help=f'R|orders results by one of the following keys:\n{format_aliases(ORDER_BY_FIELDS)}') user_id_group = parser.add_argument_group('detailed statistics') user_id_group.add_argument( '--id', type=int, help='get detailed statistics for database record with given id') user_id_group.add_argument( '--time-unit', type=time_unit_type, default=60, help='group statistics using given time, 1 minute by default; ' 'for example: 1h or 1h30m or dynamic; available only in pair with --id') parser.add_argument( '-r', '--for-reseller', type=str, help='show only statistics only about given reseller and his users' ) namespace = parser.parse_args(argv_) return argparse_process_period(namespace)