Source code for pawnlib.cli.info

#!/usr/bin/env python3
import argparse
from pawnlib.builder.generator import generate_banner
from pawnlib.__version__ import __version__ as _version
from pawnlib.config import pawn, pconf

# pawn.console.log(pconf_legacy().PAWN_CONFIG)
# pawn.console.log(pconf().PAWN_CONFIG)
# exit()
import os
from pawnlib.typing import str2bool, StackList, remove_tags, dict_to_line
from pawnlib.output import write_json, get_color_by_threshold
from rich.tree import Tree
from pawnlib.resource import (
    get_interface_ips,
    get_public_ip,
    get_hostname,
    get_platform_info,
    get_rlimit_nofile,
    get_mem_info,
    get_location,
    get_location_with_ip_api,
    DiskUsage
)

from pawnlib.resource.server import get_uptime, get_swap_usage, get_load_average

__description__ = "This command displays server resource information."

__epilog__ = (
    "This tool provides a detailed overview of your server's system and network resources.\n\n"
    "Usage examples:\n"
    "  1. Display all resource information in verbose mode:\n"
    "     - Displays detailed information about system and network resources.\n\n"
    "     `pawns info -v`\n"


    "  2. Run in quiet mode without displaying any output:\n"
    "     - Executes the script without showing any output, useful for logging purposes.\n\n"
    "     `pawns info -q`\n"


    "  3. Specify a custom base directory and configuration file:\n"
    "     - Uses the specified base directory and configuration file for operations.\n\n"
    "     `pawns info -b /path/to/base/dir --config-file my_config.ini`\n"


    "  4. Write output to a specified file in quiet mode without displaying any output:\n"
    "     - Writes the collected resource information to 'output.json'.\n\n"
    "    `pawns info -q --output-file output.json`\n\n"


    "For more detailed command usage and options, refer to the help documentation by running 'pawns info --help'."
)


[docs]def get_parser(): parser = argparse.ArgumentParser(description='monitor') parser = get_arguments(parser) return parser
[docs]def get_arguments(parser): # parser.add_argument('url', help='url', type=str, nargs='?', default="") parser.add_argument('-c', '--config-file', type=str, help='config', default="config.ini") parser.add_argument('-v', '--verbose', action='count', help='verbose mode. view level (default: %(default)s)', default=1) parser.add_argument('-q', '--quiet', action='count', help='Quiet mode. Dont show any messages. (default: %(default)s)', default=0) parser.add_argument('-b', '--base-dir', type=str, help='base dir for httping (default: %(default)s)', default=os.getcwd()) parser.add_argument('-d', '--debug', action='count', help='base dir for httping (default: %(default)s)', default=0) parser.add_argument('--ip-api-provider', type=str, help='API provider to fetch public IP information (e.g., ip-api.com, another-api.com)', default="ip-api.com") # parser.add_argument( "-o", "--output-file", type=str, help="The name of the file to write the output to.", default="", ) parser.add_argument( '-w', '--write-file', type=str, nargs='?', const='resource_info.json', help='Write the output to a file. Default file is "resource_info.json". If a filename is provided, it will be used instead.', default=None ) return parser
[docs]def main(): app_name = 'Resource Information' parser = get_parser() args, unknown = parser.parse_known_args() config_file = args.config_file pawn.console.debug(args) is_hide_line_number = args.verbose > 2 stdout = not args.quiet pawn.set( PAWN_CONFIG_FILE=config_file, PAWN_PATH=args.base_dir, PAWN_CONSOLE=dict( redirect=True, record=True, log_path=is_hide_line_number, # hide line number on the right side ), app_name=app_name, args=args, try_pass=False, last_execute_point=0, data={ "response_time": StackList(), }, fail_count=0, total_count=0, ) if args.verbose > 2: pawn.set( PAWN_LOGGER=dict( log_level="DEBUG", stdout_level="DEBUG", ) ) print_banner() result = { "system": {}, "network": {}, "disk": {}, } system_tree = Tree("[bold]🖥️ System Information[/bold]") system_tree.add(f"Hostname: {get_hostname()}") for k, v in get_platform_info().items(): system_tree.add(f"{k.title()}: {v}") result['system'][k] = v result['system']['mem_total'] = get_mem_info().get('mem_total') system_tree.add(f"Memory: {result['system']['mem_total']} GB") result['system']["resource_limit"] = get_rlimit_nofile(detail=bool(args.debug)) # system_tree.add(f"Resource limit: {result['system']['resource_limit']}") resource_tree = system_tree.add(f"Resource limit") for k, v in result['system']['resource_limit'].items(): resource_tree.add(f"{k.title()}: {v}") system_tree.add(f"Swap Usage : {get_swap_usage()}") system_tree.add(f"CPU Load : {get_load_average()}") system_tree.add(f"Uptime: {get_uptime()}") print_unless_quiet_mode(system_tree) print_unless_quiet_mode("") network_tree = Tree("[bold]🛜 Network Interface[/bold]") if args.ip_api_provider == "ip-api.com": public_ip_info = get_location_with_ip_api() if public_ip_info.get('status'): del public_ip_info['status'] result['network']['public_ip'] = {"ip": public_ip_info.get('query')} public_ip_tree = network_tree.add(f"[bold] Public IP[/bold]: {result['network']['public_ip']['ip']}") if result['network']['public_ip']: result['network']['public_ip'].update(public_ip_info) public_ip_tree.add(f"[bold] Region : {public_ip_info.get('countryCode')}, {public_ip_info.get('regionName')}, {public_ip_info.get('city')}, " f"{public_ip_info.get('country')}, Timezone={public_ip_info.get('timezone')}") public_ip_tree.add(f"[bold] ASN : {public_ip_info.get('as')}, ISP: {public_ip_info.get('isp')}, ORG: {public_ip_info.get('org')}") else: result['network']['public_ip'] = {"ip": get_public_ip()} public_ip_tree= network_tree.add(f"[bold] Public IP[/bold]: {result['network']['public_ip']['ip']}") if result['network']['public_ip']: _location = get_location(result['network']['public_ip']['ip']) if _location: result['network']['public_ip'].update(_location) public_ip_tree.add(f"[bold] Region : {_location.get('region')}, Timezone={_location.get('timezone')}") public_ip_tree.add(f"[bold] ASN : {dict_to_line(_location.get('asn'), end_separator=', ')}") local_tree = network_tree.add("[bold] Local IP[/bold]") interface_list = get_interface_ips(ignore_interfaces=['lo0', 'lo'], detail=True) if interface_list: longest_length = max(len(item[0]) for item in interface_list) for interface, ipaddr in interface_list: subnet_str = f" / {ipaddr.get('subnet')}" if ipaddr.get('subnet') else "" gateway_str = f", G/W: {ipaddr.get('gateway')}" if ipaddr.get('gateway') else "" formatted_ipaddr = f"{ipaddr.get('ip'):<10}{subnet_str}{gateway_str}" result['network'][interface] = ipaddr if "gateway" in ipaddr: interface = f"[bold blue][on #050B27]{interface:<{longest_length}} [/bold blue]" formatted_ipaddr = f"{formatted_ipaddr}[/on #050B27]" local_tree.add(f"[bold]{interface:<{longest_length+1}}[/bold]: {formatted_ipaddr}") print_unless_quiet_mode(network_tree) print_unless_quiet_mode("") disk_usage = DiskUsage() disk_usage_result = disk_usage.get_disk_usage("all", unit="auto") result['disk'] = disk_usage_result disk_tree = Tree("[bold]💾 Disk Usage[/bold]") for mount_point, usage in disk_usage_result.items(): color, percent = get_color_by_threshold(usage['percent'], return_tuple=True) color_unit = f"[grey74]{usage['unit']}[/grey74]" usage_line = f"[{color}]{usage['used']:>7}[/{color}] {color_unit}[{color}] / {usage['total']:>7}[/{color}] {color_unit} [{color}]({percent}%)[/{color}] " disk_tree.add(f"[bold blue]{mount_point:<11}[/bold blue][dim]{usage['device']}[/dim]: {usage_line}") print_unless_quiet_mode(disk_tree) if args.write_file: write_res = write_json(filename=args.write_file, data=result) pawn.console.log(write_res)
main.__doc__ = ( f"{__description__} \n" f"{__epilog__}" ) if __name__ == '__main__': try: main() except Exception as e: pawn.console.log(e)