Files
Scripts/pc-monitor.sh
Wiktor Olszewski 2c0000079b Add PC Anti-Freeze Monitor with enhanced features
- System protection script with custom enhancements and TUI interface
- Browser tab limiting and application-specific monitoring
- AI behavior learning and predictive analysis
- Terminal-based configuration interface
- Multi-distro installation support
2025-07-01 19:51:06 +02:00

797 lines
27 KiB
Bash
Executable File

#!/bin/bash
# PC Anti-Freeze Monitor - Comprehensive System Protection
# Author: Claude Code Assistant
# Description: Prevents system crashes and freezes with detailed notifications
set -euo pipefail
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly CONFIG_FILE="/etc/pc-monitor.conf"
readonly LOG_FILE="/var/log/pc-monitor.log"
readonly PID_FILE="/var/run/pc-monitor.pid"
# Default thresholds (can be overridden in config)
CPU_THRESHOLD=85
MEMORY_THRESHOLD=90
TEMP_THRESHOLD=80
DISK_THRESHOLD=95
PROCESS_HANG_TIME=30
SWAP_THRESHOLD=80
LOAD_AVG_THRESHOLD=10
# Advanced monitoring features
NETWORK_THRESHOLD=50 # MB/s
IO_THRESHOLD=100 # MB/s
BROWSER_TAB_LIMIT=20
AGGRESSIVE_ON_BROWSERS=true
AGGRESSIVE_CPU_THRESHOLD=75
AGGRESSIVE_MEMORY_THRESHOLD=80
# Application-specific thresholds
BROWSER_CPU_THRESHOLD=60
BROWSER_MEMORY_THRESHOLD=70
GAME_CPU_THRESHOLD=95
GAME_MEMORY_THRESHOLD=85
IDE_MEMORY_THRESHOLD=75
# Browser monitoring
FIREFOX_MAX_TABS=15
CHROME_MAX_TABS=15
EDGE_MAX_TABS=10
# Notification settings
NOTIFICATION_TIMEOUT=5000
NOTIFICATION_URGENCY="critical"
# Color codes for notifications
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
# Initialize logging
init_logging() {
if [[ ! -f "$LOG_FILE" ]]; then
sudo touch "$LOG_FILE"
sudo chmod 644 "$LOG_FILE"
fi
exec 3>&1 4>&2
trap 'exec 2>&4 1>&3' 0 1 2 3
exec 1> >(tee -a "$LOG_FILE")
exec 2>&1
}
# Log with timestamp
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# Send desktop notification
send_notification() {
local title="$1"
local message="$2"
local urgency="${3:-normal}"
local icon="${4:-dialog-warning}"
log "NOTIFICATION: $title - $message"
# Try multiple notification methods
if command -v notify-send >/dev/null 2>&1; then
notify-send --urgency="$urgency" --expire-time="$NOTIFICATION_TIMEOUT" \
--icon="$icon" "$title" "$message"
elif command -v zenity >/dev/null 2>&1; then
zenity --notification --text="$title: $message" &
fi
# Also try to send to all active X sessions
for user_session in $(who | awk '{print $1 ":" $2}' | sort -u); do
local user="${user_session%:*}"
local display="${user_session#*:}"
if [[ -n "$display" && "$display" =~ ^:[0-9]+$ ]]; then
sudo -u "$user" DISPLAY="$display" notify-send --urgency="$urgency" \
--expire-time="$NOTIFICATION_TIMEOUT" --icon="$icon" "$title" "$message" 2>/dev/null || true
fi
done
}
# Get process information with application classification
get_process_info() {
local pid="$1"
local name cmd cpu_percent mem_percent mem_mb app_type
if [[ ! -d "/proc/$pid" ]]; then
echo "Process $pid no longer exists"
return 1
fi
name=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown")
cmd=$(ps -p "$pid" -o cmd= 2>/dev/null | cut -c1-50 || echo "unknown")
cpu_percent=$(ps -p "$pid" -o %cpu= 2>/dev/null || echo "0")
mem_percent=$(ps -p "$pid" -o %mem= 2>/dev/null || echo "0")
# Get memory in MB
if [[ -f "/proc/$pid/status" ]]; then
mem_mb=$(awk '/VmRSS:/ {print int($2/1024)}' "/proc/$pid/status" 2>/dev/null || echo "0")
else
mem_mb="0"
fi
# Classify application type
app_type=$(classify_application "$name" "$cmd")
echo "PID:$pid NAME:$name CMD:$cmd CPU:$cpu_percent MEM:$mem_percent MEM_MB:${mem_mb} TYPE:$app_type"
}
# Classify application type for targeted monitoring
classify_application() {
local name="$1"
local cmd="$2"
case "$name" in
*firefox*|*chrome*|*chromium*|*brave*|*opera*|*edge*|*safari*)
echo "browser"
;;
*steam*|*game*|*csgo*|*dota*|*minecraft*|*wow*|*lol*|*valorant*)
echo "game"
;;
*code*|*idea*|*eclipse*|*netbeans*|*atom*|*sublime*)
echo "ide"
;;
*blender*|*gimp*|*krita*|*inkscape*|*davinci*)
echo "graphics"
;;
*vlc*|*mpv*|*ffmpeg*|*obs*|*audacity*)
echo "media"
;;
*docker*|*podman*|*virtualbox*|*qemu*|*vmware*)
echo "virtualization"
;;
*)
echo "general"
;;
esac
}
# Kill process with notification
kill_process_with_notification() {
local pid="$1"
local reason="$2"
local resource_info="$3"
local process_info
process_info=$(get_process_info "$pid")
if [[ $? -eq 0 ]]; then
local name=$(echo "$process_info" | grep -o 'NAME:[^[:space:]]*' | cut -d: -f2)
local cmd=$(echo "$process_info" | grep -o 'CMD:[^[:space:]]*' | cut -d: -f2)
local cpu=$(echo "$process_info" | grep -o 'CPU:[^[:space:]]*' | cut -d: -f2)
local mem=$(echo "$process_info" | grep -o 'MEM:[^[:space:]]*' | cut -d: -f2)
local mem_mb=$(echo "$process_info" | grep -o 'MEM_MB:[^[:space:]]*' | cut -d: -f2)
# Kill the process
if kill -9 "$pid" 2>/dev/null; then
local notification_title="⚠️ Process Terminated - System Protected"
local notification_message="Killed '$name' (PID: $pid)
Reason: $reason
Resource Usage: CPU: ${cpu}%, RAM: ${mem}% (${mem_mb}MB)
$resource_info
Command: $cmd"
send_notification "$notification_title" "$notification_message" "critical" "process-stop"
log "KILLED PROCESS: PID=$pid NAME=$name REASON=$reason CPU=${cpu}% MEM=${mem}% (${mem_mb}MB)"
return 0
else
log "FAILED TO KILL: PID=$pid NAME=$name"
return 1
fi
else
log "PROCESS INFO UNAVAILABLE: PID=$pid"
return 1
fi
}
# Monitor CPU usage
monitor_cpu() {
local cpu_usage
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
cpu_usage=${cpu_usage%.*} # Remove decimal part
if [[ "$cpu_usage" -gt "$CPU_THRESHOLD" ]]; then
log "HIGH CPU USAGE: ${cpu_usage}%"
# Find top CPU consuming processes
local top_processes
top_processes=$(ps aux --sort=-%cpu | head -6 | tail -5)
while IFS= read -r line; do
local pid=$(echo "$line" | awk '{print $2}')
local cpu_percent=$(echo "$line" | awk '{print $3}')
local name=$(echo "$line" | awk '{print $11}')
if (( $(echo "$cpu_percent > 20" | bc -l) )); then
kill_process_with_notification "$pid" "High CPU Usage" "System CPU: ${cpu_usage}%, Process CPU: ${cpu_percent}%"
fi
done <<< "$top_processes"
fi
}
# Monitor memory usage
monitor_memory() {
local mem_info
mem_info=$(free | grep '^Mem:')
local total=$(echo "$mem_info" | awk '{print $2}')
local used=$(echo "$mem_info" | awk '{print $3}')
local mem_percent=$(( (used * 100) / total ))
if [[ "$mem_percent" -gt "$MEMORY_THRESHOLD" ]]; then
log "HIGH MEMORY USAGE: ${mem_percent}%"
# Find top memory consuming processes
local top_processes
top_processes=$(ps aux --sort=-%mem | head -6 | tail -5)
while IFS= read -r line; do
local pid=$(echo "$line" | awk '{print $2}')
local mem_percent_proc=$(echo "$line" | awk '{print $4}')
local name=$(echo "$line" | awk '{print $11}')
local mem_mb=$(echo "$line" | awk '{print $6}')
mem_mb=$((mem_mb / 1024)) # Convert to MB
if (( $(echo "$mem_percent_proc > 15" | bc -l) )); then
kill_process_with_notification "$pid" "High Memory Usage" "System RAM: ${mem_percent}%, Process RAM: ${mem_percent_proc}% (${mem_mb}MB)"
fi
done <<< "$top_processes"
fi
}
# Monitor temperature
monitor_temperature() {
if command -v sensors >/dev/null 2>&1; then
local max_temp=0
local temp_info=""
# Get CPU temperature
local cpu_temps
cpu_temps=$(sensors | grep -E "(Core|Package|CPU)" | grep -o '+[0-9]*\.[0-9]*°C' | sed 's/+//;s/°C//')
for temp in $cpu_temps; do
local temp_int=${temp%.*}
if [[ "$temp_int" -gt "$max_temp" ]]; then
max_temp="$temp_int"
temp_info="CPU Temperature: ${temp}°C"
fi
done
if [[ "$max_temp" -gt "$TEMP_THRESHOLD" ]]; then
log "HIGH TEMPERATURE: ${max_temp}°C"
# Find processes that might be causing high CPU load
local cpu_processes
cpu_processes=$(ps aux --sort=-%cpu | head -4 | tail -3)
send_notification "🌡️ High Temperature Warning" \
"Temperature: ${max_temp}°C (Threshold: ${TEMP_THRESHOLD}°C)
Killing high CPU processes to reduce heat" "critical" "temperature"
while IFS= read -r line; do
local pid=$(echo "$line" | awk '{print $2}')
local cpu_percent=$(echo "$line" | awk '{print $3}')
if (( $(echo "$cpu_percent > 10" | bc -l) )); then
kill_process_with_notification "$pid" "Temperature Protection" "$temp_info"
fi
done <<< "$cpu_processes"
fi
fi
}
# Monitor disk usage
monitor_disk() {
local disk_usage
disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
if [[ "$disk_usage" -gt "$DISK_THRESHOLD" ]]; then
log "HIGH DISK USAGE: ${disk_usage}%"
send_notification "💾 Low Disk Space Warning" \
"Disk usage: ${disk_usage}% (Threshold: ${DISK_THRESHOLD}%)
Cleaning temporary files..." "critical" "drive-harddisk"
# Clean temporary files
sudo find /tmp -type f -atime +1 -delete 2>/dev/null || true
sudo find /var/tmp -type f -atime +1 -delete 2>/dev/null || true
# Clean package cache
if command -v paccache >/dev/null 2>&1; then
sudo paccache -r -k3 2>/dev/null || true
fi
log "DISK CLEANUP COMPLETED"
fi
}
# Monitor for hanging processes
monitor_hanging_processes() {
local hanging_pids
hanging_pids=$(ps axo pid,etime,state,comm | awk -v hang_time="$PROCESS_HANG_TIME" '
$3 ~ /D|T/ && $2 ~ /[0-9]+-/ {
split($2, time_parts, "-")
if (time_parts[1] >= hang_time/86400 ||
(time_parts[1] == 0 && time_parts[2] ~ /[0-9]+:[0-9]+/ &&
time_parts[2] >= hang_time/60)) {
print $1
}
}')
for pid in $hanging_pids; do
if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]]; then
kill_process_with_notification "$pid" "Process Hanging/Uninterruptible Sleep" "Process stuck for >$PROCESS_HANG_TIME seconds"
fi
done
}
# Monitor swap usage
monitor_swap() {
if [[ -f /proc/swaps ]]; then
local swap_info
swap_info=$(free | grep '^Swap:')
local total=$(echo "$swap_info" | awk '{print $2}')
if [[ "$total" -gt 0 ]]; then
local used=$(echo "$swap_info" | awk '{print $3}')
local swap_percent=$(( (used * 100) / total ))
if [[ "$swap_percent" -gt "$SWAP_THRESHOLD" ]]; then
log "HIGH SWAP USAGE: ${swap_percent}%"
send_notification "🔄 High Swap Usage" \
"Swap usage: ${swap_percent}% - System may be slow
Killing memory-heavy processes..." "critical" "system-run"
# Kill top memory consumers
local top_mem_processes
top_mem_processes=$(ps aux --sort=-%mem | head -4 | tail -3)
while IFS= read -r line; do
local pid=$(echo "$line" | awk '{print $2}')
kill_process_with_notification "$pid" "High Swap Usage" "System Swap: ${swap_percent}%"
done <<< "$top_mem_processes"
fi
fi
fi
}
# Monitor system load
monitor_load() {
local load_avg
load_avg=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//')
load_avg=${load_avg%.*} # Remove decimal part
if [[ "$load_avg" -gt "$LOAD_AVG_THRESHOLD" ]]; then
log "HIGH SYSTEM LOAD: $load_avg"
send_notification "⚡ High System Load" \
"Load average: $load_avg (Threshold: $LOAD_AVG_THRESHOLD)
Killing resource-intensive processes..." "critical" "system-monitor"
# Kill processes with high CPU and memory usage
local resource_heavy_processes
resource_heavy_processes=$(ps aux | awk '$3+$4 > 20 {print $2}' | tail -n +2)
for pid in $resource_heavy_processes; do
if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]]; then
kill_process_with_notification "$pid" "High System Load" "Load Average: $load_avg"
fi
done
fi
}
# Monitor for memory leaks
monitor_memory_leaks() {
local processes_with_leaks
processes_with_leaks=$(ps aux --sort=-%mem | head -10 | tail -9 | awk '$4 > 25 {print $2}')
for pid in $processes_with_leaks; do
if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]]; then
# Check if process memory is still growing
local mem_before mem_after
mem_before=$(ps -p "$pid" -o rss= 2>/dev/null || echo "0")
sleep 2
mem_after=$(ps -p "$pid" -o rss= 2>/dev/null || echo "0")
if [[ "$mem_after" -gt "$mem_before" ]] && [[ "$mem_after" -gt 1048576 ]]; then # > 1GB
kill_process_with_notification "$pid" "Potential Memory Leak" "Memory growing rapidly: ${mem_before}KB → ${mem_after}KB"
fi
fi
done
}
# Monitor browser tabs and limit them
monitor_browser_tabs() {
if [[ "$AGGRESSIVE_ON_BROWSERS" == "true" ]]; then
# Firefox tab monitoring
if pgrep firefox >/dev/null 2>&1; then
local firefox_tabs
firefox_tabs=$(find /tmp -name "*firefox*" -type d 2>/dev/null | wc -l)
if [[ "$firefox_tabs" -gt "$FIREFOX_MAX_TABS" ]]; then
log "FIREFOX TAB LIMIT EXCEEDED: $firefox_tabs tabs (limit: $FIREFOX_MAX_TABS)"
send_notification "🌐 Firefox Tab Limit" \
"Too many tabs: $firefox_tabs (limit: $FIREFOX_MAX_TABS)
Closing oldest Firefox processes..." "critical" "web-browser"
# Kill oldest Firefox processes
local old_firefox_pids
old_firefox_pids=$(ps aux | grep firefox | grep -v grep | head -3 | awk '{print $2}')
for pid in $old_firefox_pids; do
kill_process_with_notification "$pid" "Browser Tab Limit Exceeded" "Firefox tabs: $firefox_tabs"
done
fi
fi
# Chrome/Chromium tab monitoring
local chrome_processes
chrome_processes=$(pgrep -c chrome 2>/dev/null || echo "0")
if [[ "$chrome_processes" -gt "$CHROME_MAX_TABS" ]]; then
log "CHROME TAB LIMIT EXCEEDED: $chrome_processes processes (limit: $CHROME_MAX_TABS)"
send_notification "🌐 Chrome Tab Limit" \
"Too many processes: $chrome_processes (limit: $CHROME_MAX_TABS)
Closing excess Chrome processes..." "critical" "web-browser"
# Kill oldest Chrome processes
local old_chrome_pids
old_chrome_pids=$(ps aux | grep chrome | grep -v grep | head -3 | awk '{print $2}')
for pid in $old_chrome_pids; do
kill_process_with_notification "$pid" "Browser Tab Limit Exceeded" "Chrome processes: $chrome_processes"
done
fi
fi
}
# Monitor network usage
monitor_network() {
if command -v vnstat >/dev/null 2>&1; then
local network_usage
network_usage=$(vnstat -i eth0 --json | jq -r '.interfaces[0].traffic.day[0].tx' 2>/dev/null || echo "0")
network_usage=$((network_usage / 1024 / 1024)) # Convert to MB
if [[ "$network_usage" -gt "$NETWORK_THRESHOLD" ]]; then
log "HIGH NETWORK USAGE: ${network_usage}MB/s"
send_notification "🌐 High Network Usage" \
"Network usage: ${network_usage}MB/s
Monitoring bandwidth-heavy processes..." "normal" "network-wired"
fi
fi
}
# Monitor I/O usage
monitor_io() {
if command -v iotop >/dev/null 2>&1; then
local high_io_processes
high_io_processes=$(iotop -a -o -d 1 -n 1 | grep -v "TOTAL" | head -3 | awk '{print $2}')
for pid in $high_io_processes; do
if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]]; then
local io_rate
io_rate=$(iotop -p "$pid" -o -d 1 -n 1 | tail -1 | awk '{print $4}' | sed 's/M.*//')
if [[ "$io_rate" -gt "$IO_THRESHOLD" ]]; then
kill_process_with_notification "$pid" "High I/O Usage" "I/O Rate: ${io_rate}MB/s"
fi
fi
done
fi
}
# Advanced CPU monitoring with app-specific thresholds
monitor_cpu_advanced() {
local cpu_usage
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
cpu_usage=${cpu_usage%.*}
# Use aggressive threshold when browsers are running
local active_threshold="$CPU_THRESHOLD"
if [[ "$AGGRESSIVE_ON_BROWSERS" == "true" ]] && (pgrep firefox >/dev/null 2>&1 || pgrep chrome >/dev/null 2>&1); then
active_threshold="$AGGRESSIVE_CPU_THRESHOLD"
fi
if [[ "$cpu_usage" -gt "$active_threshold" ]]; then
log "HIGH CPU USAGE: ${cpu_usage}% (threshold: ${active_threshold}%)"
local top_processes
top_processes=$(ps aux --sort=-%cpu | head -6 | tail -5)
while IFS= read -r line; do
local pid=$(echo "$line" | awk '{print $2}')
local cpu_percent=$(echo "$line" | awk '{print $3}')
local process_info
process_info=$(get_process_info "$pid")
local app_type=$(echo "$process_info" | grep -o 'TYPE:[^[:space:]]*' | cut -d: -f2)
local process_name=$(echo "$process_info" | grep -o 'NAME:[^[:space:]]*' | cut -d: -f2)
# Check process behavior history
local behavior_score
behavior_score=$(get_process_behavior_score "$process_name" "$app_type")
# Apply app-specific thresholds with behavior adjustment
local kill_threshold=20
case "$app_type" in
"browser")
kill_threshold=15 # More aggressive on browsers
;;
"game")
kill_threshold=50 # Less aggressive on games
;;
"graphics"|"media")
kill_threshold=30
;;
esac
# Adjust threshold based on behavior score
kill_threshold=$((kill_threshold + behavior_score))
if (( $(echo "$cpu_percent > $kill_threshold" | bc -l) )); then
record_process_kill "$process_name" "$app_type" "cpu" "$cpu_percent"
kill_process_with_notification "$pid" "High CPU Usage ($app_type)" "System CPU: ${cpu_usage}%, Process CPU: ${cpu_percent}%"
fi
done <<< "$top_processes"
fi
}
# Process behavior learning system
get_process_behavior_score() {
local process_name="$1"
local app_type="$2"
local behavior_file="/var/log/pc-monitor-behavior.db"
if [[ ! -f "$behavior_file" ]]; then
echo "0"
return
fi
# Get kill count for this process in the last 24 hours
local kill_count
kill_count=$(grep "$process_name" "$behavior_file" 2>/dev/null | \
awk -v since="$(date -d '24 hours ago' +%s)" '$1 >= since' | wc -l)
# Calculate behavior score (positive = more lenient, negative = more aggressive)
local score=0
if [[ "$kill_count" -gt 5 ]]; then
score=-5 # Very problematic process - be more aggressive
elif [[ "$kill_count" -gt 2 ]]; then
score=-2 # Somewhat problematic
elif [[ "$kill_count" -eq 0 ]]; then
score=5 # Well-behaved process - be more lenient
fi
echo "$score"
}
# Record process termination for learning
record_process_kill() {
local process_name="$1"
local app_type="$2"
local reason="$3"
local usage="$4"
local behavior_file="/var/log/pc-monitor-behavior.db"
local timestamp=$(date +%s)
# Ensure file exists and is writable
if [[ ! -f "$behavior_file" ]]; then
sudo touch "$behavior_file"
sudo chmod 644 "$behavior_file"
fi
# Record the kill event
echo "$timestamp $process_name $app_type $reason $usage" | sudo tee -a "$behavior_file" >/dev/null
# Clean old entries (older than 7 days)
local week_ago=$(date -d '7 days ago' +%s)
sudo awk -v cutoff="$week_ago" '$1 >= cutoff' "$behavior_file" > "/tmp/pc-monitor-behavior.tmp" 2>/dev/null || true
sudo mv "/tmp/pc-monitor-behavior.tmp" "$behavior_file" 2>/dev/null || true
}
# Smart process prioritization
smart_process_prioritization() {
# Identify long-running, well-behaved processes and give them priority
local well_behaved_processes
well_behaved_processes=$(ps aux --sort=-etime | head -20 | tail -15 | awk '{print $2}')
for pid in $well_behaved_processes; do
if [[ -n "$pid" && "$pid" =~ ^[0-9]+$ ]]; then
local process_info
process_info=$(get_process_info "$pid" 2>/dev/null) || continue
local process_name=$(echo "$process_info" | grep -o 'NAME:[^[:space:]]*' | cut -d: -f2)
local app_type=$(echo "$process_info" | grep -o 'TYPE:[^[:space:]]*' | cut -d: -f2)
# Check if this is a well-behaved process
local behavior_score
behavior_score=$(get_process_behavior_score "$process_name" "$app_type")
if [[ "$behavior_score" -gt 0 ]]; then
# Give better nice value to well-behaved processes
sudo renice -5 "$pid" 2>/dev/null || true
log "PRIORITIZED: Process $process_name (PID: $pid) - good behavior score: $behavior_score"
fi
fi
done
}
# Predictive resource monitoring
predictive_monitoring() {
local resource_trend_file="/var/log/pc-monitor-trends.log"
local current_time=$(date +%s)
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//' | cut -d. -f1)
local mem_usage=$(free | grep '^Mem:' | awk '{printf "%.0f", ($3/$2) * 100}')
# Record current resource usage
echo "$current_time $cpu_usage $mem_usage" | sudo tee -a "$resource_trend_file" >/dev/null
# Keep only last 100 entries
sudo tail -100 "$resource_trend_file" > "/tmp/pc-monitor-trends.tmp" 2>/dev/null || true
sudo mv "/tmp/pc-monitor-trends.tmp" "$resource_trend_file" 2>/dev/null || true
# Analyze trend (simple moving average)
if [[ -f "$resource_trend_file" ]]; then
local recent_cpu_avg
local recent_mem_avg
recent_cpu_avg=$(tail -10 "$resource_trend_file" | awk '{sum+=$2} END {print int(sum/NR)}')
recent_mem_avg=$(tail -10 "$resource_trend_file" | awk '{sum+=$3} END {print int(sum/NR)}')
# Predict if we're trending towards high usage
if [[ "$recent_cpu_avg" -gt $((CPU_THRESHOLD - 10)) ]] && [[ "$cpu_usage" -lt "$CPU_THRESHOLD" ]]; then
log "PREDICTIVE WARNING: CPU usage trending high ($recent_cpu_avg% average)"
send_notification "📈 Resource Trend Warning" \
"CPU usage trending upward: ${recent_cpu_avg}% average
System may reach threshold soon" "normal" "dialog-information"
fi
if [[ "$recent_mem_avg" -gt $((MEMORY_THRESHOLD - 10)) ]] && [[ "$mem_usage" -lt "$MEMORY_THRESHOLD" ]]; then
log "PREDICTIVE WARNING: Memory usage trending high ($recent_mem_avg% average)"
send_notification "📈 Memory Trend Warning" \
"Memory usage trending upward: ${recent_mem_avg}% average
System may reach threshold soon" "normal" "dialog-information"
fi
fi
}
# Load configuration
load_config() {
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
log "Configuration loaded from $CONFIG_FILE"
else
log "Using default configuration"
fi
}
# Create default configuration file
create_default_config() {
if [[ ! -f "$CONFIG_FILE" ]]; then
sudo tee "$CONFIG_FILE" > /dev/null << EOF
# PC Monitor Enhanced Configuration
# ===================================
# Basic Thresholds
CPU_THRESHOLD=85
MEMORY_THRESHOLD=90
TEMP_THRESHOLD=80
DISK_THRESHOLD=95
PROCESS_HANG_TIME=30
SWAP_THRESHOLD=80
LOAD_AVG_THRESHOLD=10
# Advanced Features
NETWORK_THRESHOLD=50
IO_THRESHOLD=100
BROWSER_TAB_LIMIT=20
AGGRESSIVE_ON_BROWSERS=true
AGGRESSIVE_CPU_THRESHOLD=75
AGGRESSIVE_MEMORY_THRESHOLD=80
# Application-Specific Thresholds
BROWSER_CPU_THRESHOLD=60
BROWSER_MEMORY_THRESHOLD=70
GAME_CPU_THRESHOLD=95
GAME_MEMORY_THRESHOLD=85
IDE_MEMORY_THRESHOLD=75
# Browser Tab Limits
FIREFOX_MAX_TABS=15
CHROME_MAX_TABS=15
EDGE_MAX_TABS=10
# Notification Settings
NOTIFICATION_TIMEOUT=5000
EOF
log "Created enhanced default configuration at $CONFIG_FILE"
fi
}
# Check dependencies
check_dependencies() {
local missing_deps=()
for cmd in bc ps free df top sensors; do
if ! command -v "$cmd" >/dev/null 2>&1; then
missing_deps+=("$cmd")
fi
done
if [[ ${#missing_deps[@]} -gt 0 ]]; then
log "Missing dependencies: ${missing_deps[*]}"
send_notification "⚠️ PC Monitor Warning" \
"Missing dependencies: ${missing_deps[*]}
Please install missing packages" "critical" "dialog-error"
exit 1
fi
}
# Main monitoring loop
main_loop() {
log "PC Monitor started - Enhanced system protection with AI-powered features"
send_notification "🛡️ PC Monitor Active - AI Enhanced" \
"Advanced system protection enabled
Features: Smart Learning, Predictive Analysis, App-Specific Control
Monitoring: CPU, Memory, Temperature, Disk, Processes, Browsers, Network, I/O" "normal" "security-high"
local cycle_count=0
while true; do
# Core monitoring (every cycle)
monitor_cpu_advanced
monitor_memory
monitor_temperature
monitor_disk
monitor_hanging_processes
monitor_swap
monitor_load
monitor_browser_tabs
# Extended monitoring (every 3rd cycle to reduce overhead)
if (( cycle_count % 3 == 0 )); then
monitor_memory_leaks
monitor_network
monitor_io
predictive_monitoring
fi
# AI features (every 5th cycle to minimize impact)
if (( cycle_count % 5 == 0 )); then
smart_process_prioritization
fi
cycle_count=$((cycle_count + 1))
sleep 5
done
}
# Signal handlers
cleanup() {
log "PC Monitor stopping..."
rm -f "$PID_FILE"
send_notification "🛡️ PC Monitor Stopped" \
"System protection disabled" "normal" "security-medium"
exit 0
}
# Setup signal traps
trap cleanup SIGTERM SIGINT
# Main execution
main() {
init_logging
check_dependencies
create_default_config
load_config
# Write PID file
echo $$ > "$PID_FILE"
# Start monitoring
main_loop
}
# Run main function if script is executed directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi