Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions tools/config_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from memory_process_profiler import memory_process_profiler
from file_descriptor_process_profiler import file_descriptor_process_profiler
from thread_process_profiler import thread_process_profiler
from global_system_processes_profiler import global_system_processes_profiler

# Menu ANSI Colors
BLACK = '\033[30m'
Expand Down Expand Up @@ -102,8 +103,9 @@ def display_menu():
print("1. Create General Process Profiler")
print("2. Create Memory Process Profiler")
print("3. Create File Descriptor Profiler")
print("4. Create Thread Descriptor Profiler")
print("5. Exit")
print("4. Create Thread Profiler")
print("5. Create Global System Processes Profiler")
print("6. Exit")
watch_list_choice = input(f"\n{BRIGHT_CYAN}Enter your choice (1-5):{RESET}\n")
if watch_list_choice == '1':
clear_screen()
Expand All @@ -122,6 +124,10 @@ def display_menu():
thread_process_profiler()
break
if watch_list_choice == '5':
clear_screen()
global_system_processes_profiler()
break
if watch_list_choice == '6':
break
print(f"\n{BLACK}{BACKGROUND_BRIGHT_MAGENTA}Invalid choice. Please try again.{RESET}")
elif top_choice == '4':
Expand Down
106 changes: 106 additions & 0 deletions tools/global_system_processes_profiler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/usr/bin/env python3

import os
import textwrap

# Base Directory
base_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(base_dir)

# Menu ANSI Colors
BLACK = '\033[30m'
GREEN = '\033[32m'
BRIGHT_GREEN = '\033[92m'
BRIGHT_CYAN = '\033[96m'
BRIGHT_YELLOW = '\033[93m'
BACKGROUND_BRIGHT_MAGENTA = '\033[105m'
RESET = '\033[0m'

# Reset Screen
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')

# Write configuration file to watch_list directory
def write_to_file(filename, template):
try:
with open(os.path.join(os.pardir, "watch_list", filename), 'w', encoding="utf-8") as file:
file.write(template)
clear_screen()
print(f"\n{GREEN}'{filename}' configuration created.{RESET}")
except Exception as e:
print(f"{BLACK}{BACKGROUND_BRIGHT_MAGENTA}\nAn error occurred: {e}{RESET}")

# Global System Processes Profiler Menu
def global_system_processes_profiler():
print(f"\n{BRIGHT_GREEN}GLOBAL SYSTEM PROCESSES PROFILER SETTINGS:{RESET}")
filename = "system-processes"
while True:
try:
interval = int(input(f"\n{BRIGHT_CYAN}Enter the monitoring interval {GREEN}(in seconds, recommend 1800 (30min)){RESET}:{RESET}\n"))
break
except ValueError:
print(f"{BLACK}{BACKGROUND_BRIGHT_MAGENTA}\nInvalid input. Please enter a number of seconds.{RESET}")

template = f"""
# Global System Processes Profiler
import os
import sys
import time
import logging
import threading
import psutil
import operator
import subprocess

global_system_processes_profiler_file = (f"{{str(os.getcwd())}}/logs/glbl-sys-procs-profiler.log")
error_file = (f"{{str(os.getcwd())}}/logs/error.log")

# Global File Descriptor Counter

def get_top_processes(num_top=5):
processes = []
for proc in psutil.process_iter(['pid', 'name', 'num_threads', 'num_fds', 'memory_info', 'cpu_percent']):
try:
processes.append(proc.info)
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass

top_threads = sorted(processes, key=lambda p: p['num_threads'], reverse=True)[:num_top]
top_fds = sorted(processes, key=lambda p: p['num_fds'], reverse=True)[:num_top]
top_memory = sorted(processes, key=lambda p: p['memory_info'].rss, reverse=True)[:num_top]
top_cpu = sorted(processes, key=lambda p: p['cpu_percent'], reverse=True)[:num_top]

return top_threads, top_fds, top_memory, top_cpu

def monitor():
while True:
try:
top_threads, top_fds, top_memory, top_cpu = get_top_processes()
with open(global_system_processes_profiler_file, "a", encoding="utf-8") as f:
f.write(f"########### Top 5 Memory (RSS) Consumers - {{time.ctime()}} ###########\\n")
for proc in top_memory:
f.write(f"{{time.ctime()}} - Top Memory (RSS) Consumer - Name: {{proc['name']}}, PID: {{proc['pid']}}, Memory (RSS): {{proc['memory_info'].rss}} bytes\\n")
f.write(f"########### Top 5 CPU Consumers - {{time.ctime()}} ###########\\n")
for proc in top_cpu:
f.write(f"{{time.ctime()}} - Top CPU Consumer - Name: {{proc['name']}}, PID: {{proc['pid']}}, CPU: {{proc['cpu_percent']}}%\\n")
f.write(f"########### Top 5 Thread Consumers - {{time.ctime()}} ###########\\n")
for proc in top_threads:
f.write(f"{{time.ctime()}} - Top Thread Consumer - Name: {{proc['name']}}, PID: {{proc['pid']}}, Threads: {{proc['num_threads']}}\\n")
f.write(f"########### Top 5 File Descriptor Consumers - {{time.ctime()}} ###########\\n")
for proc in top_fds:
f.write(f"{{time.ctime()}} - Top File Descriptor Consumer - Name: {{proc['name']}}, PID: {{proc['pid']}}, File Descriptors: {{proc['num_fds']}}\\n")
time.sleep({interval})
except Exception as e:
print(f"An error occurred in Process Watch configuration file {filename}: {{e}}")
with open(error_file, "a", encoding="utf-8") as file:
file.write(str(e) + (f" in {filename}") + "\\n")
raise sys.exit(1)

def worker():
monitor_thread = threading.Thread(target=monitor)
monitor_thread.start()

worker()
"""
# Write the template into a config
write_to_file(os.path.abspath(f"../watch_list/{filename}_glbl.py"), textwrap.dedent(template))
8 changes: 4 additions & 4 deletions tools/memory_process_profiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def write_to_file(filename, template):

# Memory Process Profiler Menu
def memory_process_profiler():
print(f"\n{BRIGHT_GREEN}MEMORY PROCESS PROFILER SETTINGS:{RESET}")
print(f"\n{BRIGHT_GREEN}MEMORY (RSS) PROCESS PROFILER SETTINGS:{RESET}")
filename = input(f"\n{BRIGHT_CYAN}Enter the name of the configuration file:{RESET}\n")
sanitized_filename = filename.replace(".", "-")
process_name = input(f"\n{BRIGHT_CYAN}Enter the process name to monitor {GREEN}(use name in ps ouput){RESET}:{RESET}\n")
Expand All @@ -51,7 +51,7 @@ def memory_process_profiler():
action = input(f"\n{BRIGHT_CYAN}Enter the action to take upon the memory threshold being met {GREEN}(leave blank for no action){RESET}:{RESET}\n") or "echo"

template = f"""
# Memory Process Profiler
# Memory (RSS) Process Profiler
import os
import sys
import time
Expand Down Expand Up @@ -96,10 +96,10 @@ def monitor():
process_memory = int(process_memory_set.pop())
if int(process_memory) >= {memory_threshold}:
with open(memory_process_profiler_file, "a", encoding="utf-8") as f:
f.write(f"{{time.ctime()}} - Memory Alert - Above Threshold {memory_threshold} MB - Process: [ {process_name} ], PID: {{int(find_pid_by_name('{process_name}'))}}, Memory: {{find_memory_usage_by_pid(int(find_pid_by_name('{process_name}')))}} MB\\n")
f.write(f"{{time.ctime()}} - Memory (RSS) Alert - Above Threshold {memory_threshold} MB - Process: [ {process_name} ], PID: {{int(find_pid_by_name('{process_name}'))}}, Memory: {{find_memory_usage_by_pid(int(find_pid_by_name('{process_name}')))}} MB\\n")
process_action = subprocess.run(['{action}'], capture_output=True, text=True)
time.sleep(5)
f.write(f"{{time.ctime()}} - Memory Alert - After Remediation - Action Taken: [ {action} ], Process: [ {process_name} ], PID: {{int(find_pid_by_name('{process_name}'))}}, Memory: {{find_memory_usage_by_pid(int(find_pid_by_name('{process_name}')))}} MB\\n")
f.write(f"{{time.ctime()}} - Memory (RSS) Alert - After Remediation - Action Taken: [ {action} ], Process: [ {process_name} ], PID: {{int(find_pid_by_name('{process_name}'))}}, Memory: {{find_memory_usage_by_pid(int(find_pid_by_name('{process_name}')))}} MB\\n")
time.sleep({interval})
except Exception as e:
print(f"An error occurred in Process Watch configuration file {sanitized_filename}: {{e}}")
Expand Down