├── README.md └── SysTracker.py /README.md: -------------------------------------------------------------------------------- 1 | # SysTracker 2 | Display system information using this GUI application 3 | 4 | ## Information displayed: 5 | - System Information 6 | - Network Information 7 | - Booting Information 8 | - CPU Information 9 | - Memory Information 10 | - Disk Information 11 | - GPU Information (if any attached) 12 | 13 | ## Demo screenshot: 14 | ![ss1](https://user-images.githubusercontent.com/64016811/136903000-b6e94984-eeba-43df-a3d9-5b80dcf63555.png) 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /SysTracker.py: -------------------------------------------------------------------------------- 1 | import psutil 2 | import platform 3 | import GPUtil 4 | from datetime import datetime 5 | from tkinter import * 6 | import webbrowser 7 | 8 | root = Tk() 9 | root.title('SysTracker') 10 | root.geometry('680x450') 11 | root.resizable(False, False) 12 | root.config(bg='#1d0238') 13 | 14 | Label(root, text='SysTracker : System Info Display', font='Arial 20 bold', fg='#f2bc94', bg="#1d0238",pady=30).pack() 15 | TextBox = Text(root, height=15, width=57, font='Verdana 10 bold') 16 | TextBox.place(x = 140, y= 145) 17 | 18 | 19 | 20 | def get_size(bytes, suffix="B"): 21 | 22 | factor = 1024 23 | for unit in ["", "K", "M", "G", "T", "P"]: 24 | if bytes < factor: 25 | return f"{bytes:.2f}{unit}{suffix}" 26 | bytes /= factor 27 | 28 | def SystemInfo(): 29 | TextBox.delete('1.0', END) 30 | TextBox.insert(END, '______________System Information______________\n\n') 31 | uname = platform.uname() 32 | TextBox.insert(END, f"System: {uname.system}\n") 33 | TextBox.insert(END, f"Node Name: {uname.node}\n") 34 | TextBox.insert(END, f"Release: {uname.release}\n") 35 | TextBox.insert(END, f"Version: {uname.version}\n") 36 | TextBox.insert(END, f"Machine: {uname.machine}\n") 37 | TextBox.insert(END, f"Processor: {uname.processor}") 38 | 39 | # Boot Time 40 | def boottime(): 41 | TextBox.delete('1.0', END) 42 | TextBox.insert(END, '______________BOOT TIME______________\n\n') 43 | boot_time_timestamp = psutil.boot_time() 44 | bt = datetime.fromtimestamp(boot_time_timestamp) 45 | TextBox.insert(END, f"Boot Time: {bt.year}/{bt.month}/{bt.day} {bt.hour}:{bt.minute}:{bt.second}") 46 | 47 | # let's print CPU information 48 | def CPUInfo(): 49 | TextBox.delete('1.0', END) 50 | TextBox.insert(END, '______________CPU INFORMATION______________\n\n') 51 | # number of cores 52 | TextBox.insert(END, f"Physical cores: {psutil.cpu_count(logical=False)}\n") 53 | TextBox.insert(END, f"Total cores: {psutil.cpu_count(logical=True)}\n") 54 | # CPU frequencies 55 | cpufreq = psutil.cpu_freq() 56 | TextBox.insert(END, f"Max Frequency: {cpufreq.max:.2f}Mhz \n") 57 | TextBox.insert(END, f"Min Frequency: {cpufreq.min:.2f}Mhz \n") 58 | TextBox.insert(END, f"Current Frequency: {cpufreq.current:.2f}Mhz \n") 59 | # CPU usage 60 | TextBox.insert(END, "CPU Usage Per Core: \n") 61 | for i, percentage in enumerate(psutil.cpu_percent(percpu=True, interval=1)): 62 | TextBox.insert(END, f"Core {i}: {percentage}% \n") 63 | TextBox.insert(END, f"Total CPU Usage: {psutil.cpu_percent()}% \n\n") 64 | 65 | TextBox.insert(END, "___ BATTERY INFO ___ \n") 66 | info = list(psutil.sensors_battery()) 67 | TextBox.insert(END, f" Percentage: {info[0]}\n") 68 | TextBox.insert(END, f" Plugged-in: {info[2]}") 69 | 70 | # Memory Information 71 | def MemoryInfo(): 72 | TextBox.delete('1.0', END) 73 | TextBox.insert(END, '______________MEMORY(RAM) INFORMATION______________\n\n') 74 | # get the memory details 75 | svmem = psutil.virtual_memory() 76 | TextBox.insert(END, f"Total: {get_size(svmem.total)} \n") 77 | TextBox.insert(END, f"Available: {get_size(svmem.available)} \n") 78 | TextBox.insert(END, f"Used: {get_size(svmem.used)} \n") 79 | TextBox.insert(END, f"Percentage: {svmem.percent}% \n") 80 | 81 | # get the swap memory details (if exists) 82 | TextBox.insert(END, "______________SWAP MEMORY DETAILS (if exist)___________\n\n") 83 | swap = psutil.swap_memory() 84 | TextBox.insert(END, f"Total: {get_size(swap.total)} \n") 85 | TextBox.insert(END, f"Free: {get_size(swap.free)} \n") 86 | TextBox.insert(END, f"Used: {get_size(swap.used)} \n") 87 | TextBox.insert(END, f"Percentage: {swap.percent}% ") 88 | 89 | # Disk Information 90 | def DiskInfo(): 91 | TextBox.delete('1.0', END) 92 | TextBox.insert(END, '______________DISK INFORMATION______________\n\n') 93 | TextBox.insert(END, "Partitions and Usage:\n") 94 | # get all disk partitions 95 | partitions = psutil.disk_partitions() 96 | for partition in partitions: 97 | TextBox.insert(END, f"=== Device: {partition.device} === \n") 98 | TextBox.insert(END, f" Mountpoint: {partition.mountpoint} \n") 99 | TextBox.insert(END, f" File system type: {partition.fstype} \n") 100 | try: 101 | partition_usage = psutil.disk_usage(partition.mountpoint) 102 | except PermissionError: 103 | # this can be catched due to the disk that 104 | # isn't ready 105 | continue 106 | TextBox.insert(END, f" Total Size: {get_size(partition_usage.total)} \n") 107 | TextBox.insert(END, f" Used: {get_size(partition_usage.used)} \n") 108 | TextBox.insert(END, f" Free: {get_size(partition_usage.free)} \n") 109 | TextBox.insert(END, f" Percentage: {partition_usage.percent}% \n\n") 110 | # get IO statistics since boot 111 | disk_io = psutil.disk_io_counters() 112 | TextBox.insert(END, f"Total read: {get_size(disk_io.read_bytes)} \n") 113 | TextBox.insert(END, f"Total write: {get_size(disk_io.write_bytes)} ") 114 | 115 | # Network information 116 | def NetworkInfo(): 117 | TextBox.delete('1.0', END) 118 | TextBox.insert(END, '______________NETWORK INFORMATION______________\n\n') 119 | # get all network interfaces (virtual and physical) 120 | if_addrs = psutil.net_if_addrs() 121 | for interface_name, interface_addresses in if_addrs.items(): 122 | for address in interface_addresses: 123 | TextBox.insert(END, f"=== Interface: {interface_name} === \n") 124 | if str(address.family) == 'AddressFamily.AF_INET': 125 | TextBox.insert(END, f" IP Address: {address.address} \n") 126 | TextBox.insert(END, f" Netmask: {address.netmask} \n") 127 | TextBox.insert(END, f" Broadcast IP: {address.broadcast} \n") 128 | elif str(address.family) == 'AddressFamily.AF_PACKET': 129 | TextBox.insert(END, f" MAC Address: {address.address} \n") 130 | TextBox.insert(END, f" Netmask: {address.netmask} \n") 131 | TextBox.insert(END, f" Broadcast MAC: {address.broadcast} \n") 132 | # get IO statistics since boot 133 | net_io = psutil.net_io_counters() 134 | TextBox.insert(END, f"Total Bytes Sent: {get_size(net_io.bytes_sent)} \n") 135 | TextBox.insert(END, f"Total Bytes Received: {get_size(net_io.bytes_recv)} \n") 136 | 137 | # GPU information 138 | def GPUInfo(): 139 | TextBox.delete('1.0', END) 140 | TextBox.insert(END, '______________GPU INFORMATION______________\n\n') 141 | gpus = GPUtil.getGPUs() 142 | for gpu in gpus: 143 | # get the GPU id 144 | TextBox.insert(END, f" GPU ID : {gpu.id} \n") 145 | # name of GPU 146 | TextBox.insert(END, f"GPU NAME : {gpu.name} \n") 147 | # get % percentage of GPU usage of that GPU 148 | TextBox.insert(END, f"Load : {gpu.load*100}% \n") 149 | # get free memory in MB format 150 | TextBox.insert(END, f"Memory Free : {gpu.memoryFree}MB \n") 151 | # get used memory 152 | TextBox.insert(END, f"Memory Used : {gpu.memoryUsed}MB \n") 153 | # get total memory 154 | TextBox.insert(END, f"Memory Total : {gpu.memoryTotal}MB \n") 155 | # get GPU temperature in Celsius 156 | TextBox.insert(END, f"Temperature : {gpu.temperature} °C \n") 157 | TextBox.insert(END, f"vvid : {gpu.uuid}") 158 | 159 | def About(): 160 | webbrowser.open('https://www.linkedin.com/in/mainak-chaudhuri-127898176/') 161 | Button(root, text='System Info', bg='#ffee00', fg='#00154f', font='Verdana 10 bold', width=10,relief=RIDGE, command=SystemInfo).place(x=20, y=100) 162 | Button(root, text='Boot Time', bg='#f5a2fc', fg='#00154f', font='Verdana 10 bold', width=10,relief=RIDGE, command=boottime).place(x=170, y=100) 163 | Button(root, text='CPU Info', bg='#f5a2fc', fg='#00154f', font='Verdana 10 bold', width=10,relief=RIDGE, command= CPUInfo).place(x=290, y=100) 164 | Button(root, text='Memory Info', bg='#f5a2fc', fg='#00154f', font='Verdana 10 bold', width=10,relief=RIDGE, command=MemoryInfo).place(x=410, y=100) 165 | Button(root, text='Disk Info', bg='#f5a2fc', fg='#00154f', font='Verdana 10 bold', width=10,relief=RIDGE, command=DiskInfo).place(x=530, y=100) 166 | Button(root, text='Network Info', bg='#ffee00', fg='#00154f', font='Verdana 10 bold', width=10,relief=RIDGE, command = NetworkInfo).place(x=20, y=170) 167 | Button(root, text='GPU Info', bg='#ffee00', fg='#00154f', font='Verdana 10 bold', width=10,relief=RIDGE, command=GPUInfo).place(x=20, y=235) 168 | Button(root, text='About', bg='#ffee00', fg='#00154f', font='Verdana 10 bold', width=10,relief=RIDGE, command=About).place(x=20, y=300) 169 | Button(root, text='Exit', bg='#ffee00', fg='#00154f', font='Verdana 10 bold', width=10,relief=RIDGE, command=exit).place(x=20, y=360) 170 | 171 | 172 | root.mainloop() --------------------------------------------------------------------------------