Files
Scripts/fix-service.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

337 lines
11 KiB
Bash
Executable File

#!/bin/bash
# PC Monitor Service Fix Script
# Fixes notification issues with systemd service
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
print_status() {
echo -e "${GREEN}[FIX]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_header() {
echo -e "${BLUE}================================${NC}"
echo -e "${BLUE} PC Monitor Service Fixer${NC}"
echo -e "${BLUE}================================${NC}"
}
# Check if running as root
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root (use sudo)"
exit 1
fi
print_header
# Stop the failing service
print_status "Stopping current service..."
systemctl stop pc-monitor.service 2>/dev/null || true
# Create fixed version of the script
print_status "Creating fixed PC Monitor script..."
cat > /usr/local/bin/pc-monitor << 'EOF'
#!/bin/bash
# PC Anti-Freeze Monitor - Fixed for Systemd
set -euo pipefail
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
CPU_THRESHOLD=85
MEMORY_THRESHOLD=90
TEMP_THRESHOLD=80
DISK_THRESHOLD=95
PROCESS_HANG_TIME=30
SWAP_THRESHOLD=80
LOAD_AVG_THRESHOLD=10
# Initialize logging
exec 1> >(tee -a "$LOG_FILE")
exec 2>&1
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# Fixed notification system for systemd
send_notification() {
local title="$1"
local message="$2"
local urgency="${3:-normal}"
log "NOTIFICATION: $title - $message"
# Find active user sessions using loginctl (systemd-aware)
if command -v loginctl >/dev/null 2>&1; then
loginctl list-sessions --no-header 2>/dev/null | while read session_info; do
local session_id=$(echo "$session_info" | awk '{print $1}')
# Get session details
local user_name=$(loginctl show-session "$session_id" -p Name --value 2>/dev/null || continue)
local session_type=$(loginctl show-session "$session_id" -p Type --value 2>/dev/null || continue)
# Only send to graphical sessions
if [[ "$session_type" == "x11" || "$session_type" == "wayland" ]]; then
# Try to find the user's DISPLAY
local display_var=""
if pgrep -u "$user_name" -x "Xorg\|X" >/dev/null 2>&1; then
display_var=":0"
elif pgrep -u "$user_name" -f "wayland\|weston" >/dev/null 2>&1; then
display_var="wayland-0"
fi
if [[ -n "$display_var" ]]; then
sudo -u "$user_name" DISPLAY="$display_var" \
notify-send --urgency="$urgency" --expire-time=5000 \
--icon="dialog-warning" "$title" "$message" 2>/dev/null || true
fi
fi
done
fi
# Fallback: try to find any active X session
for display_file in /tmp/.X11-unix/X*; do
if [[ -e "$display_file" ]]; then
local display_num="${display_file##*/X}"
# Find user running X session
local x_user=$(ps aux | grep "[X]org.*:$display_num" | awk '{print $1}' | head -1)
if [[ -n "$x_user" && "$x_user" != "root" ]]; then
sudo -u "$x_user" DISPLAY=":$display_num" \
notify-send --urgency="$urgency" --expire-time=5000 \
--icon="dialog-warning" "$title" "$message" 2>/dev/null || true
fi
fi
done
}
# Get process information
get_process_info() {
local pid="$1"
if [[ ! -d "/proc/$pid" ]]; then
return 1
fi
local name=$(ps -p "$pid" -o comm= 2>/dev/null || echo "unknown")
local cpu_percent=$(ps -p "$pid" -o %cpu= 2>/dev/null || echo "0")
local mem_percent=$(ps -p "$pid" -o %mem= 2>/dev/null || echo "0")
local mem_mb=$(awk '/VmRSS:/ {print int($2/1024)}' "/proc/$pid/status" 2>/dev/null || echo "0")
echo "NAME:$name CPU:$cpu_percent MEM:$mem_percent MEM_MB:$mem_mb"
}
# Kill process with notification
kill_process_with_notification() {
local pid="$1"
local reason="$2"
local resource_info="$3"
local process_info=$(get_process_info "$pid")
if [[ $? -eq 0 ]]; then
local name=$(echo "$process_info" | grep -o 'NAME:[^[: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)
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"
send_notification "$notification_title" "$notification_message" "critical"
log "KILLED PROCESS: PID=$pid NAME=$name REASON=$reason CPU=${cpu}% MEM=${mem}% (${mem_mb}MB)"
return 0
fi
fi
return 1
}
# Monitor CPU usage
monitor_cpu() {
local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//' | cut -d. -f1)
if [[ "$cpu_usage" -gt "$CPU_THRESHOLD" ]]; then
log "HIGH CPU USAGE: ${cpu_usage}%"
# Find top CPU consuming processes
ps aux --sort=-%cpu | head -6 | tail -5 | while read line; do
local pid=$(echo "$line" | awk '{print $2}')
local cpu_percent=$(echo "$line" | awk '{print $3}')
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
fi
}
# Monitor memory usage
monitor_memory() {
local 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
ps aux --sort=-%mem | head -6 | tail -5 | while read line; do
local pid=$(echo "$line" | awk '{print $2}')
local mem_percent_proc=$(echo "$line" | awk '{print $4}')
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}%"
fi
done
fi
}
# Monitor temperature
monitor_temperature() {
if command -v sensors >/dev/null 2>&1; then
local max_temp=0
local cpu_temps=$(sensors 2>/dev/null | grep -E "(Core|Package|CPU)" | grep -o '+[0-9]*\.[0-9]*°C' | sed 's/+//;s/°C//' || echo "0")
for temp in $cpu_temps; do
local temp_int=${temp%.*}
if [[ "$temp_int" -gt "$max_temp" ]]; then
max_temp="$temp_int"
fi
done
if [[ "$max_temp" -gt "$TEMP_THRESHOLD" ]]; then
log "HIGH TEMPERATURE: ${max_temp}°C"
send_notification "🌡️ High Temperature Warning" \
"Temperature: ${max_temp}°C (Threshold: ${TEMP_THRESHOLD}°C)
Killing high CPU processes to reduce heat" "critical"
# Kill top CPU processes
ps aux --sort=-%cpu | head -4 | tail -3 | while read 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" "CPU Temperature: ${max_temp}°C"
fi
done
fi
fi
}
# Monitor disk usage
monitor_disk() {
local 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"
# Clean temporary files
find /tmp -type f -atime +1 -delete 2>/dev/null || true
find /var/tmp -type f -atime +1 -delete 2>/dev/null || true
# Clean package cache
if command -v paccache >/dev/null 2>&1; then
paccache -r -k3 2>/dev/null || true
fi
fi
}
# Load configuration
if [[ -f "$CONFIG_FILE" ]]; then
source "$CONFIG_FILE"
log "Configuration loaded from $CONFIG_FILE"
fi
# Write PID file
echo $$ > "$PID_FILE"
# Main monitoring loop
log "PC Monitor started - Protecting your system from crashes and freezes"
send_notification "🛡️ PC Monitor Active" \
"System protection enabled
Monitoring: CPU, Memory, Temperature, Disk, Processes" "normal"
while true; do
monitor_cpu
monitor_memory
monitor_temperature
monitor_disk
sleep 5
done
EOF
# Make script executable
chmod +x /usr/local/bin/pc-monitor
# Update service file to be more permissive
print_status "Updating service configuration..."
cat > /etc/systemd/system/pc-monitor.service << 'EOF'
[Unit]
Description=PC Anti-Freeze Monitor - System Crash Prevention
Documentation=man:pc-monitor(8)
After=multi-user.target graphical-session.target
Wants=multi-user.target
[Service]
Type=simple
ExecStart=/usr/local/bin/pc-monitor
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=always
RestartSec=10
User=root
Group=root
# Environment for notifications
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Resource limits
LimitNOFILE=1024
LimitNPROC=512
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd and start service
print_status "Reloading systemd and starting service..."
systemctl daemon-reload
systemctl start pc-monitor.service
# Check if it's working
sleep 3
if systemctl is-active --quiet pc-monitor.service; then
print_status "✅ PC Monitor is now running successfully!"
systemctl status pc-monitor.service --no-pager --lines=5
else
print_error "❌ Service still failing. Checking logs..."
journalctl -u pc-monitor.service --no-pager -n 10
fi
print_status "🛡️ Your system is now protected from crashes and freezes!"
echo
echo "Useful commands:"
echo " • Check status: systemctl status pc-monitor"
echo " • View logs: journalctl -u pc-monitor -f"
echo " • Stop service: systemctl stop pc-monitor"
echo " • Restart service: systemctl restart pc-monitor"