Files
Wiktor 610db394a8 feat(analytics,backup,boot-monitor,security,service,api): add advanced analytics, backup, boot monitoring, security, and performance features
- Introduce analytics-engine.sh for system and module metrics, anomaly detection, and reporting
- Enhance backup-engine.sh with incremental backups, compression, encryption, and progress tracking
- Upgrade boot-monitor.sh with ML-based anomaly detection, adaptive timeouts, and predictive failure analysis
- Add security-framework.sh for advanced security, encryption, session management, and intrusion detection
- Improve service.sh with performance monitoring, job management, and optimized service startup
- Extend webroot/js/api.js with caching, rate limiting, performance metrics, and robust command execution

These changes provide comprehensive monitoring, security, and backup capabilities with improved reliability and performance.

Co-authored-by: terragon-labs[bot] <terragon-labs[bot]@users.noreply.github.com>
2025-07-21 18:12:30 +00:00

478 lines
17 KiB
Bash
Executable File

#!/system/bin/sh
# KernelSU Anti-Bootloop & Backup Module - Analytics Engine
# Advanced monitoring, analytics, and reporting system
MODDIR=${0%/*}
MODDIR=${MODDIR%/*}
CONFIG_DIR="$MODDIR/config"
ANALYTICS_DIR="$CONFIG_DIR/analytics"
ML_DATA_DIR="$CONFIG_DIR/ml_data"
REPORTS_DIR="$CONFIG_DIR/reports"
METRICS_DIR="$CONFIG_DIR/metrics"
# Advanced analytics configuration
ANALYTICS_INTERVAL=30 # seconds
METRIC_RETENTION_DAYS=30
REPORT_GENERATION_INTERVAL=3600 # 1 hour
ANOMALY_THRESHOLD=2.5 # standard deviations
TREND_ANALYSIS_WINDOW=7 # days
# Ensure directories exist
mkdir -p "$ANALYTICS_DIR" "$ML_DATA_DIR" "$REPORTS_DIR" "$METRICS_DIR"
# Enhanced logging
log_message() {
local level="${2:-INFO}"
local timestamp="$(date +"%Y-%m-%d %H:%M:%S")"
echo "[$timestamp] [analytics:$level] $1" >> "$CONFIG_DIR/analytics_engine.log"
# Structured logging
echo "{\"timestamp\":$(date +%s),\"level\":\"$level\",\"component\":\"analytics\",\"message\":\"$1\"}" >> "$ANALYTICS_DIR/structured.log"
}
# System metrics collection
collect_system_metrics() {
local timestamp=$(date +%s)
# CPU metrics
local cpu_usage=$(top -n1 | grep "CPU:" | awk '{print $2}' | sed 's/%//')
local load_avg=$(uptime | awk '{print $3 $4 $5}' | sed 's/,//g')
# Memory metrics
local mem_total=$(grep MemTotal /proc/meminfo | awk '{print $2}')
local mem_free=$(grep MemFree /proc/meminfo | awk '{print $2}')
local mem_available=$(grep MemAvailable /proc/meminfo | awk '{print $2}')
local mem_usage=$((100 - (mem_available * 100 / mem_total)))
# Storage metrics
local storage_info=$(df /data | tail -1)
local storage_used=$(echo $storage_info | awk '{print $5}' | sed 's/%//')
local storage_total=$(echo $storage_info | awk '{print $2}')
local storage_free=$(echo $storage_info | awk '{print $4}')
# Process metrics
local process_count=$(ps | wc -l)
local zombie_processes=$(ps aux | grep -c " Z ")
# Network metrics (if available)
local network_rx=$(cat /proc/net/dev | grep -E "(wlan|eth|rmnet)" | head -1 | awk '{print $2}' || echo 0)
local network_tx=$(cat /proc/net/dev | grep -E "(wlan|eth|rmnet)" | head -1 | awk '{print $10}' || echo 0)
# I/O metrics
local io_read=$(cat /proc/diskstats | head -1 | awk '{print $6}' || echo 0)
local io_write=$(cat /proc/diskstats | head -1 | awk '{print $10}' || echo 0)
# Create comprehensive metrics JSON
local metrics="{
\"timestamp\": $timestamp,
\"system\": {
\"uptime\": $(cat /proc/uptime | awk '{print $1}'),
\"boot_time\": $((timestamp - $(cat /proc/uptime | awk '{print $1}'))),
\"kernel_version\": \"$(uname -r)\",
\"architecture\": \"$(uname -m)\"
},
\"cpu\": {
\"usage_percent\": ${cpu_usage:-0},
\"load_average\": \"$load_avg\",
\"cores\": $(nproc),
\"frequency\": $(cat /proc/cpuinfo | grep -m1 "cpu MHz" | awk '{print $4}' || echo 0)
},
\"memory\": {
\"total_kb\": $mem_total,
\"free_kb\": $mem_free,
\"available_kb\": $mem_available,
\"usage_percent\": $mem_usage,
\"swap_total\": $(grep SwapTotal /proc/meminfo | awk '{print $2}'),
\"swap_free\": $(grep SwapFree /proc/meminfo | awk '{print $2}')
},
\"storage\": {
\"usage_percent\": $storage_used,
\"total_kb\": $storage_total,
\"free_kb\": $storage_free,
\"inodes_used\": $(df -i /data | tail -1 | awk '{print $5}' | sed 's/%//')
},
\"processes\": {
\"count\": $process_count,
\"zombies\": $zombie_processes,
\"running\": $(ps aux | grep -c " R ")
},
\"network\": {
\"rx_bytes\": $network_rx,
\"tx_bytes\": $network_tx
},
\"io\": {
\"read_sectors\": $io_read,
\"write_sectors\": $io_write
}
}"
echo "$metrics" >> "$METRICS_DIR/system_metrics.jsonl"
# Also update latest metrics file
echo "$metrics" > "$ANALYTICS_DIR/latest_metrics.json"
log_message "System metrics collected" "DEBUG"
}
# Module-specific metrics collection
collect_module_metrics() {
local timestamp=$(date +%s)
# Boot metrics
local boot_count=$(cat "$CONFIG_DIR/boot_counter" 2>/dev/null || echo 0)
local last_boot_time=$(stat -c %Y "$CONFIG_DIR/boot_counter" 2>/dev/null || echo 0)
# Safety metrics
local bootloop_detected=$([ -f "$CONFIG_DIR/bootloop_detected" ] && echo "true" || echo "false")
local safe_mode_active=$([ -f "$CONFIG_DIR/safe_mode/active" ] && echo "true" || echo "false")
# Backup metrics
local backup_count=$(ls -1 "$CONFIG_DIR/backups" 2>/dev/null | wc -l)
local last_backup_time=0
if [ -d "$CONFIG_DIR/backups" ]; then
last_backup_time=$(stat -c %Y "$CONFIG_DIR/backups" 2>/dev/null || echo 0)
fi
# Recovery metrics
local recovery_points=$(ls -1 "$CONFIG_DIR/recovery_points" 2>/dev/null | wc -l)
# WebUI metrics
local webui_active=$(pgrep -f "webui-server" >/dev/null && echo "true" || echo "false")
local webui_connections=$(netstat -an 2>/dev/null | grep ":8080" | grep ESTABLISHED | wc -l)
# Performance metrics
local service_start_time=0
if [ -f "$CONFIG_DIR/performance/service_summary.json" ]; then
service_start_time=$(grep -o '"total_duration_ms":[0-9]*' "$CONFIG_DIR/performance/service_summary.json" | cut -d: -f2)
fi
local module_metrics="{
\"timestamp\": $timestamp,
\"module_info\": {
\"version\": \"$(grep version= $MODDIR/module.prop | cut -d= -f2)\",
\"version_code\": \"$(grep versionCode= $MODDIR/module.prop | cut -d= -f2)\",
\"author\": \"$(grep author= $MODDIR/module.prop | cut -d= -f2)\"
},
\"boot\": {
\"count\": $boot_count,
\"last_boot_timestamp\": $last_boot_time,
\"bootloop_detected\": $bootloop_detected,
\"safe_mode_active\": $safe_mode_active
},
\"backup\": {
\"count\": $backup_count,
\"last_backup_timestamp\": $last_backup_time,
\"recovery_points\": $recovery_points
},
\"webui\": {
\"active\": $webui_active,
\"connections\": $webui_connections
},
\"performance\": {
\"service_start_duration_ms\": ${service_start_time:-0}
}
}"
echo "$module_metrics" >> "$METRICS_DIR/module_metrics.jsonl"
echo "$module_metrics" > "$ANALYTICS_DIR/latest_module_metrics.json"
log_message "Module metrics collected" "DEBUG"
}
# Advanced anomaly detection using statistical analysis
detect_anomalies() {
local metric_file="$1"
local field="$2"
local threshold="${3:-$ANOMALY_THRESHOLD}"
if [ ! -f "$metric_file" ]; then
return 0
fi
# Get last 50 values for statistical analysis
local values=$(tail -50 "$metric_file" | grep -o "\"$field\":[0-9.]*" | cut -d: -f2)
local count=$(echo "$values" | wc -l)
if [ "$count" -lt 10 ]; then
return 0 # Not enough data
fi
# Calculate mean and standard deviation (simplified)
local sum=0
local sum_squared=0
for value in $values; do
sum=$((sum + value))
sum_squared=$((sum_squared + value * value))
done
local mean=$((sum / count))
local variance=$((sum_squared / count - mean * mean))
local std_dev=$(echo "scale=2; sqrt($variance)" | bc -l 2>/dev/null || echo 1)
# Get current value
local current=$(tail -1 "$metric_file" | grep -o "\"$field\":[0-9.]*" | cut -d: -f2)
if [ -n "$current" ]; then
local deviation=$(echo "scale=2; ($current - $mean) / $std_dev" | bc -l 2>/dev/null || echo 0)
local abs_deviation=$(echo "$deviation" | sed 's/-//')
# Check if deviation exceeds threshold
if [ "$(echo "$abs_deviation > $threshold" | bc -l 2>/dev/null)" = "1" ]; then
# Anomaly detected
local anomaly_report="{
\"timestamp\": $(date +%s),
\"metric\": \"$field\",
\"current_value\": $current,
\"mean\": $mean,
\"std_dev\": $std_dev,
\"deviation\": $deviation,
\"threshold\": $threshold,
\"severity\": $(echo "$abs_deviation > 3.0" | bc -l 2>/dev/null | grep -q 1 && echo "high" || echo "medium")
}"
echo "$anomaly_report" >> "$ANALYTICS_DIR/anomalies.jsonl"
log_message "Anomaly detected in $field: deviation=$deviation, threshold=$threshold" "WARN"
return 1
fi
fi
return 0
}
# Generate comprehensive system report
generate_system_report() {
local report_timestamp=$(date +%s)
local report_file="$REPORTS_DIR/system_report_$(date +%Y%m%d_%H%M%S).json"
log_message "Generating comprehensive system report" "INFO"
# System overview
local uptime_seconds=$(cat /proc/uptime | awk '{print $1}')
local uptime_days=$(echo "scale=1; $uptime_seconds / 86400" | bc -l)
# Recent metrics analysis
local recent_cpu_avg=0
local recent_mem_avg=0
local recent_storage_avg=0
if [ -f "$METRICS_DIR/system_metrics.jsonl" ]; then
recent_cpu_avg=$(tail -20 "$METRICS_DIR/system_metrics.jsonl" | grep -o '"usage_percent":[0-9]*' | cut -d: -f2 | awk '{sum+=$1} END {print int(sum/NR)}')
recent_mem_avg=$(tail -20 "$METRICS_DIR/system_metrics.jsonl" | grep -o '"usage_percent":[0-9]*' | cut -d: -f2 | awk '{sum+=$1} END {print int(sum/NR)}')
fi
# Anomaly summary
local anomaly_count=0
if [ -f "$ANALYTICS_DIR/anomalies.jsonl" ]; then
anomaly_count=$(wc -l < "$ANALYTICS_DIR/anomalies.jsonl")
fi
# Performance summary
local avg_boot_time=0
if [ -f "$CONFIG_DIR/performance/service_summary.json" ]; then
avg_boot_time=$(grep -o '"total_duration_ms":[0-9]*' "$CONFIG_DIR/performance/service_summary.json" | cut -d: -f2)
fi
# Create comprehensive report
cat > "$report_file" << EOF
{
"report_timestamp": $report_timestamp,
"report_type": "system_health",
"period": "last_24_hours",
"system_overview": {
"uptime_days": $uptime_days,
"kernel_version": "$(uname -r)",
"device_model": "$(getprop ro.product.model 2>/dev/null || echo 'Unknown')",
"android_version": "$(getprop ro.build.version.release 2>/dev/null || echo 'Unknown')"
},
"performance_metrics": {
"average_cpu_usage": $recent_cpu_avg,
"average_memory_usage": $recent_mem_avg,
"average_boot_time_ms": $avg_boot_time,
"anomalies_detected": $anomaly_count
},
"module_status": {
"version": "$(grep version= $MODDIR/module.prop | cut -d= -f2)",
"boot_count": $(cat "$CONFIG_DIR/boot_counter" 2>/dev/null || echo 0),
"backup_count": $(ls -1 "$CONFIG_DIR/backups" 2>/dev/null | wc -l),
"recovery_points": $(ls -1 "$CONFIG_DIR/recovery_points" 2>/dev/null | wc -l),
"safe_mode_active": $([ -f "$CONFIG_DIR/safe_mode/active" ] && echo true || echo false)
},
"health_score": {
"overall": $(calculate_health_score),
"cpu": $(calculate_component_health "cpu"),
"memory": $(calculate_component_health "memory"),
"storage": $(calculate_component_health "storage")
},
"recommendations": $(generate_recommendations)
}
EOF
log_message "System report generated: $report_file" "INFO"
}
# Calculate overall system health score (0-100)
calculate_health_score() {
local score=100
# Check anomalies
if [ -f "$ANALYTICS_DIR/anomalies.jsonl" ]; then
local recent_anomalies=$(tail -100 "$ANALYTICS_DIR/anomalies.jsonl" | wc -l)
score=$((score - recent_anomalies * 2))
fi
# Check bootloop status
if [ -f "$CONFIG_DIR/bootloop_detected" ]; then
score=$((score - 30))
fi
# Check safe mode
if [ -f "$CONFIG_DIR/safe_mode/active" ]; then
score=$((score - 20))
fi
# Ensure score is within bounds
if [ $score -lt 0 ]; then
score=0
fi
echo $score
}
# Calculate component-specific health score
calculate_component_health() {
local component="$1"
local score=100
case "$component" in
"cpu")
if [ -f "$METRICS_DIR/system_metrics.jsonl" ]; then
local avg_usage=$(tail -20 "$METRICS_DIR/system_metrics.jsonl" | grep -o '"usage_percent":[0-9]*' | cut -d: -f2 | awk '{sum+=$1} END {print int(sum/NR)}')
if [ "$avg_usage" -gt 80 ]; then
score=$((score - 20))
elif [ "$avg_usage" -gt 60 ]; then
score=$((score - 10))
fi
fi
;;
"memory")
if [ -f "$METRICS_DIR/system_metrics.jsonl" ]; then
local avg_usage=$(tail -20 "$METRICS_DIR/system_metrics.jsonl" | grep -A5 '"memory"' | grep -o '"usage_percent":[0-9]*' | cut -d: -f2 | awk '{sum+=$1} END {print int(sum/NR)}')
if [ "$avg_usage" -gt 85 ]; then
score=$((score - 25))
elif [ "$avg_usage" -gt 70 ]; then
score=$((score - 10))
fi
fi
;;
"storage")
local storage_usage=$(df /data | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$storage_usage" -gt 90 ]; then
score=$((score - 30))
elif [ "$storage_usage" -gt 80 ]; then
score=$((score - 15))
fi
;;
esac
echo $score
}
# Generate actionable recommendations
generate_recommendations() {
local recommendations="[]"
# Check for high resource usage
if [ -f "$METRICS_DIR/system_metrics.jsonl" ]; then
local cpu_usage=$(tail -1 "$METRICS_DIR/system_metrics.jsonl" | grep -o '"usage_percent":[0-9]*' | cut -d: -f2)
if [ "$cpu_usage" -gt 80 ]; then
recommendations='["Consider reducing background processes or checking for CPU-intensive modules"]'
fi
fi
# Check storage space
local storage_usage=$(df /data | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$storage_usage" -gt 85 ]; then
if [ "$recommendations" = "[]" ]; then
recommendations='["Free up storage space by cleaning old backups or logs"]'
else
recommendations=$(echo "$recommendations" | sed 's/\]/, "Free up storage space by cleaning old backups or logs"\]/')
fi
fi
echo "$recommendations"
}
# Main monitoring loop
main_monitoring_loop() {
log_message "Starting advanced analytics monitoring loop" "INFO"
local last_report_time=0
while true; do
# Collect metrics
collect_system_metrics
collect_module_metrics
# Perform anomaly detection
detect_anomalies "$METRICS_DIR/system_metrics.jsonl" "usage_percent"
detect_anomalies "$METRICS_DIR/system_metrics.jsonl" "usage_percent" # Memory usage
# Generate periodic reports
local current_time=$(date +%s)
if [ $((current_time - last_report_time)) -gt $REPORT_GENERATION_INTERVAL ]; then
generate_system_report
last_report_time=$current_time
fi
# Cleanup old data
cleanup_old_data
# Sleep until next collection
sleep $ANALYTICS_INTERVAL
done
}
# Cleanup old analytics data
cleanup_old_data() {
local cutoff_time=$(($(date +%s) - METRIC_RETENTION_DAYS * 86400))
# Clean old metrics
for metric_file in "$METRICS_DIR"/*.jsonl; do
if [ -f "$metric_file" ]; then
awk -v cutoff=$cutoff_time '{if (match($0, /"timestamp": *([0-9]+)/, arr) && arr[1] > cutoff) print}' "$metric_file" > "$metric_file.tmp" && mv "$metric_file.tmp" "$metric_file"
fi
done
# Clean old reports
find "$REPORTS_DIR" -name "*.json" -mtime +$METRIC_RETENTION_DAYS -delete 2>/dev/null
log_message "Cleaned old analytics data" "DEBUG"
}
# Command processing
case "$1" in
"start")
log_message "Starting analytics engine" "INFO"
main_monitoring_loop
;;
"collect")
collect_system_metrics
collect_module_metrics
;;
"report")
generate_system_report
;;
"health")
echo "Health Score: $(calculate_health_score)%"
;;
*)
echo "Usage: $0 {start|collect|report|health}"
echo " start - Start continuous monitoring"
echo " collect - Collect metrics once"
echo " report - Generate system report"
echo " health - Show health score"
exit 1
;;
esac