Skip to content

Commit

Permalink
Merge pull request #6 from yunkon-kim/patch-yunkon-kim-1
Browse files Browse the repository at this point in the history
Update system_info.py and README
  • Loading branch information
seokho-son authored Oct 19, 2023
2 parents 8e33f44 + 045ac21 commit f9501cd
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ src/rttmap.csv

log/
*.history

# Files generated by Python virtual environment
.venv/
9 changes: 9 additions & 0 deletions scripts/system-info/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ It can be useful for extracting and referencing the configuration of the source
This script helps to quickly understand the current state of the system and diagnose issues.
It is useful for checking and referencing the configuration of the source computing environment for the cloud migrator project.

## Tested on
- `Python 3.8.10`
- `pip 20.0.2`

## Dependencies

Expand All @@ -13,6 +16,12 @@ It is useful for checking and referencing the configuration of the source comput
- `netifaces`
- `pyyaml`
- `GPUtil`
- `distro`

### Install dependencies
```bash
pip3 install -r requirements.txt
```

## Execution

Expand Down
5 changes: 5 additions & 0 deletions scripts/system-info/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distro==1.8.0
netifaces==0.11.0
prettytable==3.9.0
psutil==5.9.6
PyYAML==6.0.1
126 changes: 88 additions & 38 deletions scripts/system-info/system_info.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import platform
import distro
import socket
import psutil
import subprocess
Expand All @@ -12,19 +13,34 @@
# Optional packages for GPU and Graphic Card information
try:
import GPUtil

GPU_AVAILABLE = True
except ImportError:
GPU_AVAILABLE = False


def bytes_to_gb(bytes_value):
"""Convert bytes to gigabytes."""
return round(bytes_value / (1024 ** 3), 2)
return round(bytes_value / (1024**3), 2)


def get_os_info():
"""Fetch Operating System information."""
boot_time = datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
logged_user = os.getlogin()
try:
logged_user = os.getlogin()
except OSError:
logged_user = os.getenv("USER") or os.getenv("USERNAME")
uname_info = platform.uname()

try:
dist = platform.linux_distribution()
except AttributeError:
name = distro.name() # e.g.: 'Ubuntu'
version = distro.version() # e.g.: '20.04'
codename = distro.codename() # e.g.: 'focal'
dist = f"{name} {version} {codename.capitalize()}"

return "OS", [
("Name", platform.system()),
("Version", platform.version()),
Expand All @@ -33,9 +49,10 @@ def get_os_info():
("Boot Time", boot_time),
("Logged User", logged_user),
("Kernel Version", uname_info.release),
("Distribution", ' '.join(platform.linux_distribution()))
("Distribution", dist),
]


def get_cpu_info():
"""Fetch CPU information."""
cpu_info = psutil.cpu_freq()
Expand All @@ -51,9 +68,10 @@ def get_cpu_info():
("Architecture", platform.machine()),
("User Time (%)", cpu_times_percent.user),
("System Time (%)", cpu_times_percent.system),
("Idle Time (%)", cpu_times_percent.idle)
("Idle Time (%)", cpu_times_percent.idle),
]


def get_memory_info():
"""Fetch Memory information."""
virtual_memory = psutil.virtual_memory()
Expand All @@ -65,31 +83,33 @@ def get_memory_info():
("Cached (GB)", bytes_to_gb(virtual_memory.cached)),
("Swap Total (GB)", bytes_to_gb(swap_memory.total)),
("Swap Free (GB)", bytes_to_gb(swap_memory.free)),
("Swap Used (GB)", bytes_to_gb(swap_memory.used))
("Swap Used (GB)", bytes_to_gb(swap_memory.used)),
]


def get_disk_info():
"""Fetch Disk information."""
disk_info = psutil.disk_usage('/')
disk_info = psutil.disk_usage("/")
disk_io = psutil.disk_io_counters()
partitions = psutil.disk_partitions()
partition_info = ', '.join([p.device for p in partitions])
# partitions = psutil.disk_partitions()
# partition_info = ", ".join([p.device for p in partitions])
return "Disk", [
("Total (GB)", bytes_to_gb(disk_info.total)),
("Free (GB)", bytes_to_gb(disk_info.free)),
("Used (GB)", bytes_to_gb(disk_info.used)),
("Read Count", disk_io.read_count),
("Write Count", disk_io.write_count)
#("Partitions", partition_info),
#("File System Types", ', '.join([p.fstype for p in partitions]))
# ("Partitions", partition_info),
# ("File System Types", ', '.join([p.fstype for p in partitions]))
]


def get_network_info():
"""Fetch Network information."""
net_info = psutil.net_if_addrs()
net_stats = psutil.net_if_stats()
active_interfaces = [k for k, v in net_stats.items() if v.isup]
mac_address = 'Unknown'
mac_address = "Unknown"
for interface, addrs in net_info.items():
for addr in addrs:
if addr.family == psutil.AF_LINK:
Expand All @@ -99,11 +119,12 @@ def get_network_info():
("Hostname", socket.gethostname()),
("IP Address", socket.gethostbyname(socket.gethostname())),
("MAC Address", mac_address),
("Active Interfaces", ', '.join(active_interfaces)),
("Active Interfaces", ", ".join(active_interfaces)),
("Gateway", socket.gethostbyname(socket.gethostname())),
("DNS", socket.gethostbyname(socket.getfqdn()))
("DNS", socket.gethostbyname(socket.getfqdn())),
]


# IP and MAC addresses using netifaces
def get_advanced_network_info():
"""Fetch advanced network information using netifaces."""
Expand All @@ -114,17 +135,18 @@ def get_advanced_network_info():
addresses = netifaces.ifaddresses(iface)
if netifaces.AF_INET in addresses:
ip_info = addresses[netifaces.AF_INET][0]
ip = ip_info.get('addr', 'N/A')
netmask = ip_info.get('netmask', 'N/A')
broadcast = ip_info.get('broadcast', 'N/A')
ip = ip_info.get("addr", "N/A")
netmask = ip_info.get("netmask", "N/A")
broadcast = ip_info.get("broadcast", "N/A")
if netifaces.AF_LINK in addresses:
mac_info = addresses[netifaces.AF_LINK][0]
mac = mac_info.get('addr', 'N/A')
mac = mac_info.get("addr", "N/A")
iface_info.append((iface, ip, netmask, broadcast, mac))
else:
iface_info.append((iface, ip, netmask, broadcast, 'N/A'))
iface_info.append((iface, ip, netmask, broadcast, "N/A"))
return "Advanced Network", iface_info


def get_gpu_info():
"""Fetch GPU information if available."""
info_list = []
Expand All @@ -136,15 +158,23 @@ def get_gpu_info():
info_list.append(("Status", "Not Available"))
return "GPU", info_list


def get_graphic_card_info():
try:
lspci_output = subprocess.check_output("lspci | grep VGA", shell=True, text=True)
info_list = [("VGA Compatible Controller", line.split(":")[-1].strip()) for line in lspci_output.split("\n") if line]
lspci_output = subprocess.check_output(
"lspci | grep VGA", shell=True, text=True
)
info_list = [
("VGA Compatible Controller", line.split(":")[-1].strip())
for line in lspci_output.split("\n")
if line
]
except Exception:
info_list = [("Status", "Not Available")]

return "Graphic Card", info_list


# New function to get IP and MAC addresses using netifaces
def get_advanced_network_info():
"""Fetch advanced network information using netifaces."""
Expand All @@ -155,23 +185,24 @@ def get_advanced_network_info():
addresses = netifaces.ifaddresses(iface)
if netifaces.AF_INET in addresses:
ip_info = addresses[netifaces.AF_INET][0]
ip = ip_info.get('addr', 'N/A')
netmask = ip_info.get('netmask', 'N/A')
broadcast = ip_info.get('broadcast', 'N/A')
ip = ip_info.get("addr", "N/A")
netmask = ip_info.get("netmask", "N/A")
broadcast = ip_info.get("broadcast", "N/A")
if netifaces.AF_LINK in addresses:
mac_info = addresses[netifaces.AF_LINK][0]
mac = mac_info.get('addr', 'N/A')
mac = mac_info.get("addr", "N/A")
iface_info.append((iface, ip, netmask, broadcast, mac))
else:
iface_info.append((iface, ip, netmask, broadcast, 'N/A'))
iface_info.append((iface, ip, netmask, broadcast, "N/A"))
return "Advanced Network", iface_info


def get_process_info():
"""Fetch Process information."""
process_dict = defaultdict(list)

for proc in psutil.process_iter(['name', 'username']):
process_dict[proc.info['username']].append(proc.info['name'])
for proc in psutil.process_iter(["name", "username"]):
process_dict[proc.info["username"]].append(proc.info["name"])

# Sorting and grouping by username
sorted_process = defaultdict(list)
Expand All @@ -190,11 +221,11 @@ def get_process_info():
for prefix, names in temp.items():
line = ""
for name in names:
if len(line + name + ', ') > 80:
if len(line + name + ", ") > 80:
grouped_process[username].append(line[:-2])
line = ""
line += name + ', '
line += name + ", "

if line:
grouped_process[username].append(line[:-2])

Expand All @@ -206,12 +237,14 @@ def get_process_info():

return "Process", sorted(process_list)


# New function to save system information to a YAML file
def save_to_yaml(data):
"""Save dictionary data to YAML file."""
with open('system_info.yaml', 'w') as file:
with open("system_info.yaml", "w") as file:
yaml.dump(data, file, default_flow_style=False)


def main():
"""Main function to collect and print all system information and save it to YAML."""
system_table = PrettyTable()
Expand All @@ -227,7 +260,7 @@ def main():
get_disk_info,
get_network_info,
get_gpu_info,
get_graphic_card_info
get_graphic_card_info,
]

for func in info_functions:
Expand All @@ -242,17 +275,33 @@ def main():

# Fetch advanced network information using netifaces
advanced_network_table = PrettyTable()
advanced_network_table.field_names = ["Interface", "IP Address", "Netmask", "Broadcast", "MAC Address"]

advanced_network_table.field_names = [
"Interface",
"IP Address",
"Netmask",
"Broadcast",
"MAC Address",
]

_, advanced_network_info = get_advanced_network_info()
advanced_network_data = []
for row in advanced_network_info:
advanced_network_table.add_row(row)
advanced_network_data.append({"Interface": row[0], "IP Address": row[1], "Netmask": row[2], "Broadcast": row[3], "MAC Address": row[4]})

advanced_network_data.append(
{
"Interface": row[0],
"IP Address": row[1],
"Netmask": row[2],
"Broadcast": row[3],
"MAC Address": row[4],
}
)

print("\nAdvanced Network Information:")
print(advanced_network_table)
system_info["Advanced Network"] = advanced_network_data # Add to system info dictionary
system_info[
"Advanced Network"
] = advanced_network_data # Add to system info dictionary

# Fetch process information
process_table = PrettyTable()
Expand All @@ -270,5 +319,6 @@ def main():

save_to_yaml(system_info) # Save all gathered info to a YAML file


if __name__ == "__main__":
main()
main()

0 comments on commit f9501cd

Please sign in to comment.