Files
linux_system_tuning/monitor.sh
mindesbunister 2edb4a73c3 Complete Linux system optimization suite with tmpfs, zram, and German locale support
- Fixed missing setup_tmpfs() function that was causing silent failures
- Added comprehensive system scanning for browsers, IDEs, gaming caches
- Implemented detailed optimization information display for transparency
- Added German locale compatibility for 'free' command (Speicher: vs Mem:)
- Fixed division by zero errors in RAM calculations
- Created tmpfs-info.sh helper script for detailed status reporting
- Enhanced scanning to work on already-optimized systems
- Added comprehensive optimization breakdowns with purpose explanations
2025-09-23 12:11:45 +02:00

426 lines
12 KiB
Bash
Executable File

#!/bin/bash
# System Monitoring and Health Check
# Part of Linux System Tuning Suite
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_DIR="/var/log/system-tuning"
METRICS_FILE="$LOG_DIR/metrics.log"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log() {
echo -e "${BLUE}[$(date '+%H:%M:%S')]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
show_usage() {
cat << EOF
System Monitoring Tool
Usage: $0 [OPTIONS] [MODE]
OPTIONS:
-h, --help Show this help message
-l, --log Log metrics to file
-d, --duration SEC Monitoring duration in seconds (default: continuous)
MODES:
status Show current status (default)
live Live monitoring with updates
benchmark Run performance benchmarks
health Health check of optimizations
compare Compare performance before/after
export Export metrics for external analysis
EXAMPLES:
$0 # Show current status
$0 live # Live monitoring
$0 health # Health check
$0 benchmark # Run benchmarks
EOF
}
setup_logging() {
if [[ ! -d "$LOG_DIR" ]]; then
sudo mkdir -p "$LOG_DIR"
sudo chown $USER:$USER "$LOG_DIR" 2>/dev/null || true
fi
}
collect_metrics() {
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# Memory metrics
local mem_info=$(free -m | awk '/^Mem:/{printf "total:%s,used:%s,free:%s,available:%s", $2,$3,$4,$7}')
local swap_info=$(free -m | awk '/^Swap:/{printf "total:%s,used:%s,free:%s", $2,$3,$4}')
# zram metrics
local zram_info=""
if [[ -e /dev/zram0 ]]; then
local zram_size=$(cat /sys/block/zram0/disksize 2>/dev/null || echo "0")
local zram_used=$(cat /sys/block/zram0/compr_data_size 2>/dev/null || echo "0")
local zram_orig=$(cat /sys/block/zram0/orig_data_size 2>/dev/null || echo "0")
zram_info="size:$zram_size,used:$zram_used,orig:$zram_orig"
fi
# tmpfs metrics
local tmpfs_count=$(mount -t tmpfs | wc -l)
local tmpfs_total=$(df -t tmpfs --total | tail -1 | awk '{print $2}' 2>/dev/null || echo "0")
local tmpfs_used=$(df -t tmpfs --total | tail -1 | awk '{print $3}' 2>/dev/null || echo "0")
# System load
local load_avg=$(uptime | awk -F'load average:' '{print $2}' | sed 's/^ *//')
# I/O stats
local io_stats=""
if command -v iostat >/dev/null 2>&1; then
io_stats=$(iostat -d 1 2 | tail -n +4 | awk 'NR>1{tps+=$2; read+=$3; write+=$4} END{printf "tps:%.2f,read:%.2f,write:%.2f", tps, read, write}')
fi
cat << EOF
{
"timestamp": "$timestamp",
"memory": {$mem_info},
"swap": {$swap_info},
"zram": {$zram_info},
"tmpfs": {"count": $tmpfs_count, "total_kb": $tmpfs_total, "used_kb": $tmpfs_used},
"load": "$load_avg",
"io": {$io_stats}
}
EOF
}
show_status() {
echo "🚀 System Tuning Status"
echo "======================="
echo ""
# Memory overview
echo "💾 Memory Overview:"
free -h | while IFS= read -r line; do
echo " $line"
done
echo ""
# zram status
echo "🔄 Compression (zram):"
if [[ -e /dev/zram0 ]]; then
if command -v zramctl >/dev/null 2>&1; then
zramctl | while IFS= read -r line; do
echo " $line"
done
else
local zram_size=$(cat /sys/block/zram0/disksize 2>/dev/null)
local zram_used=$(cat /sys/block/zram0/compr_data_size 2>/dev/null)
echo " Size: $((zram_size / 1024 / 1024 / 1024))GB"
echo " Used: $((zram_used / 1024 / 1024))MB"
fi
else
echo " Not configured"
fi
echo ""
# tmpfs overview
echo "📁 tmpfs Filesystems:"
df -h -t tmpfs | while IFS= read -r line; do
echo " $line"
done
echo ""
# Kernel parameters
echo "⚙️ Key Kernel Parameters:"
echo " Swappiness: $(cat /proc/sys/vm/swappiness)"
echo " Dirty ratio: $(cat /proc/sys/vm/dirty_ratio)"
echo " Dirty background ratio: $(cat /proc/sys/vm/dirty_background_ratio)"
echo " VFS cache pressure: $(cat /proc/sys/vm/vfs_cache_pressure)"
echo ""
# Service status
echo "🔧 Services:"
if systemctl is-enabled system-tuning.service >/dev/null 2>&1; then
echo " System tuning service: ✅ ENABLED"
else
echo " System tuning service: ❌ DISABLED"
fi
# Performance score
echo ""
echo "📊 Performance Score: $(calculate_performance_score)/100"
}
live_monitoring() {
local duration=${1:-0}
local count=0
echo "📊 Live System Monitoring"
echo "========================"
echo "Press Ctrl+C to stop"
echo ""
while true; do
clear
echo "🔄 Live Monitor - $(date) (Update #$((++count)))"
echo "=================================================="
echo ""
# Real-time metrics
echo "Memory Usage:"
free -h | head -2
echo ""
echo "Top tmpfs by usage:"
df -h -t tmpfs | sort -k5 -nr | head -5 | while IFS= read -r line; do
echo " $line"
done
echo ""
echo "zram compression ratio:"
if [[ -e /dev/zram0 ]]; then
local orig=$(cat /sys/block/zram0/orig_data_size 2>/dev/null || echo "0")
local compr=$(cat /sys/block/zram0/compr_data_size 2>/dev/null || echo "0")
if [[ $orig -gt 0 && $compr -gt 0 ]]; then
local ratio=$(echo "scale=2; $orig / $compr" | bc -l 2>/dev/null || echo "N/A")
echo " Compression: ${ratio}:1"
echo " Original: $((orig / 1024 / 1024))MB"
echo " Compressed: $((compr / 1024 / 1024))MB"
else
echo " No compression data available"
fi
else
echo " zram not active"
fi
echo ""
echo "System Load: $(uptime | awk -F'load average:' '{print $2}')"
# Log metrics if enabled
if [[ -f "$METRICS_FILE" ]]; then
collect_metrics >> "$METRICS_FILE"
fi
sleep 2
# Exit if duration specified and reached
if [[ $duration -gt 0 && $count -ge $duration ]]; then
break
fi
done
}
run_benchmark() {
echo "🏁 Performance Benchmark"
echo "========================"
echo ""
log "Running memory performance tests..."
# Memory speed test
echo "Memory Performance:"
if command -v dd >/dev/null 2>&1; then
echo " Write test (1GB to tmpfs):"
time (dd if=/dev/zero of=/tmp/benchmark-test bs=1M count=1024 2>/dev/null && sync)
rm -f /tmp/benchmark-test
echo ""
fi
# Application startup test
echo "Application Startup Test:"
if command -v time >/dev/null 2>&1; then
echo " Shell startup:"
time bash -c "exit" 2>&1 | grep real || echo " Could not measure"
if command -v python3 >/dev/null 2>&1; then
echo " Python startup:"
time python3 -c "pass" 2>&1 | grep real || echo " Could not measure"
fi
fi
echo ""
# I/O performance
if command -v iostat >/dev/null 2>&1; then
echo "Current I/O performance:"
iostat -x 1 1 | tail -n +4
fi
echo ""
success "Benchmark completed"
}
health_check() {
echo "🏥 System Health Check"
echo "====================="
echo ""
local issues=0
local warnings=0
# Check zram
if [[ -e /dev/zram0 ]]; then
if swapon --show | grep -q zram0; then
success "zram swap is active"
else
error "zram device exists but swap is not active"
((issues++))
fi
else
warn "zram not configured"
((warnings++))
fi
# Check tmpfs mounts
local tmpfs_count=$(mount -t tmpfs | wc -l)
if [[ $tmpfs_count -gt 5 ]]; then
success "Multiple tmpfs mounts detected ($tmpfs_count)"
else
warn "Few tmpfs mounts detected ($tmpfs_count) - consider more optimizations"
((warnings++))
fi
# Check memory usage
local mem_usage=$(free | awk '/^Mem:/{printf "%.0f", $3/$2*100}')
if [[ $mem_usage -lt 80 ]]; then
success "Memory usage is healthy ($mem_usage%)"
else
warn "High memory usage ($mem_usage%) - monitor for performance impact"
((warnings++))
fi
# Check swap usage
local swap_usage=$(free | awk '/^Swap:/{if($2>0) printf "%.0f", $3/$2*100; else print "0"}')
if [[ $swap_usage -lt 50 ]]; then
success "Swap usage is reasonable ($swap_usage%)"
else
warn "High swap usage ($swap_usage%) - consider adding more RAM"
((warnings++))
fi
# Check service status
if systemctl is-active system-tuning.service >/dev/null 2>&1; then
success "System tuning service is running"
else
warn "System tuning service is not running"
((warnings++))
fi
echo ""
echo "Health Summary:"
echo " Issues: $issues"
echo " Warnings: $warnings"
if [[ $issues -eq 0 && $warnings -eq 0 ]]; then
success "System is optimally configured! 🎉"
elif [[ $issues -eq 0 ]]; then
warn "System is mostly optimized with $warnings minor warnings"
else
error "System has $issues issues that need attention"
fi
}
calculate_performance_score() {
local score=0
# Base score
score=30
# zram bonus
[[ -e /dev/zram0 ]] && score=$((score + 20))
# tmpfs bonus
local tmpfs_count=$(mount -t tmpfs | wc -l)
if [[ $tmpfs_count -gt 8 ]]; then
score=$((score + 25))
elif [[ $tmpfs_count -gt 5 ]]; then
score=$((score + 15))
fi
# Kernel parameter optimization
local swappiness=$(cat /proc/sys/vm/swappiness)
[[ $swappiness -le 10 ]] && score=$((score + 10))
# Service bonus
systemctl is-enabled system-tuning.service >/dev/null 2>&1 && score=$((score + 15))
echo $score
}
main() {
local mode="status"
local log_metrics=false
local duration=0
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_usage
exit 0
;;
-l|--log)
log_metrics=true
shift
;;
-d|--duration)
duration="$2"
shift 2
;;
status|live|benchmark|health|compare|export)
mode="$1"
shift
;;
*)
error "Unknown option: $1"
show_usage
exit 1
;;
esac
done
# Setup logging if requested
if [[ "$log_metrics" == "true" ]]; then
setup_logging
fi
# Execute requested mode
case "$mode" in
status)
show_status
;;
live)
live_monitoring "$duration"
;;
benchmark)
run_benchmark
;;
health)
health_check
;;
*)
error "Mode '$mode' not implemented yet"
exit 1
;;
esac
}
# Run if called directly
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi