Files
arr-suite-template-bootstrap/templates/performance-monitor.sh.j2
openhands 24f2cd64e9 Initial template repository
🎬 ARR Suite Template Bootstrap - Complete Media Automation Stack

Features:
- 16 production services (Prowlarr, Sonarr, Radarr, Plex, etc.)
- One-command Ansible deployment
- VPN-protected downloads via Gluetun
- Tailscale secure access
- Production-ready security (UFW, Fail2Ban)
- Automated backups and monitoring
- Comprehensive documentation

Ready for customization and deployment to any VPS.

Co-authored-by: openhands <openhands@all-hands.dev>
2025-11-28 04:26:12 +00:00

171 lines
6.5 KiB
Django/Jinja

#!/bin/bash
# Performance monitoring script for Arrs Media Stack
# Generated by Ansible
LOG_DIR="{{ docker_root }}/logs/system"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
PERF_LOG="$LOG_DIR/performance-$(date '+%Y%m%d').log"
# Ensure log directory exists
mkdir -p "$LOG_DIR"
# Function to log with timestamp
log_perf() {
echo "[$TIMESTAMP] $1" >> "$PERF_LOG"
}
# System performance metrics
log_perf "=== PERFORMANCE METRICS ==="
# CPU Information
CPU_MODEL=$(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)
CPU_CORES=$(nproc)
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
LOAD_1MIN=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | cut -d',' -f1 | xargs)
LOAD_5MIN=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $2}' | cut -d',' -f1 | xargs)
LOAD_15MIN=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $3}' | xargs)
log_perf "CPU_INFO Model: $CPU_MODEL, Cores: $CPU_CORES"
log_perf "CPU_USAGE ${CPU_USAGE}%"
log_perf "LOAD_AVERAGE 1min: $LOAD_1MIN, 5min: $LOAD_5MIN, 15min: $LOAD_15MIN"
# Memory Information
MEMORY_TOTAL=$(free -h | grep Mem | awk '{print $2}')
MEMORY_USED=$(free -h | grep Mem | awk '{print $3}')
MEMORY_FREE=$(free -h | grep Mem | awk '{print $4}')
MEMORY_PERCENT=$(free | grep Mem | awk '{printf "%.1f", $3/$2 * 100.0}')
SWAP_USED=$(free -h | grep Swap | awk '{print $3}')
SWAP_TOTAL=$(free -h | grep Swap | awk '{print $2}')
log_perf "MEMORY_USAGE Total: $MEMORY_TOTAL, Used: $MEMORY_USED (${MEMORY_PERCENT}%), Free: $MEMORY_FREE"
log_perf "SWAP_USAGE Used: $SWAP_USED, Total: $SWAP_TOTAL"
# Disk Information
DISK_USAGE=$(df -h {{ docker_root }} | tail -1)
DISK_TOTAL=$(echo "$DISK_USAGE" | awk '{print $2}')
DISK_USED=$(echo "$DISK_USAGE" | awk '{print $3}')
DISK_AVAILABLE=$(echo "$DISK_USAGE" | awk '{print $4}')
DISK_PERCENT=$(echo "$DISK_USAGE" | awk '{print $5}')
log_perf "DISK_USAGE {{ docker_root }} - Total: $DISK_TOTAL, Used: $DISK_USED ($DISK_PERCENT), Available: $DISK_AVAILABLE"
# Media directory disk usage if different
MEDIA_DISK_USAGE=$(df -h {{ media_root }} | tail -1)
MEDIA_DISK_TOTAL=$(echo "$MEDIA_DISK_USAGE" | awk '{print $2}')
MEDIA_DISK_USED=$(echo "$MEDIA_DISK_USAGE" | awk '{print $3}')
MEDIA_DISK_AVAILABLE=$(echo "$MEDIA_DISK_USAGE" | awk '{print $4}')
MEDIA_DISK_PERCENT=$(echo "$MEDIA_DISK_USAGE" | awk '{print $5}')
log_perf "MEDIA_DISK_USAGE {{ media_root }} - Total: $MEDIA_DISK_TOTAL, Used: $MEDIA_DISK_USED ($MEDIA_DISK_PERCENT), Available: $MEDIA_DISK_AVAILABLE"
# Network Statistics
NETWORK_INTERFACE=$(ip route | grep default | awk '{print $5}' | head -1)
if [[ -n "$NETWORK_INTERFACE" ]]; then
RX_BYTES=$(cat /sys/class/net/$NETWORK_INTERFACE/statistics/rx_bytes)
TX_BYTES=$(cat /sys/class/net/$NETWORK_INTERFACE/statistics/tx_bytes)
RX_PACKETS=$(cat /sys/class/net/$NETWORK_INTERFACE/statistics/rx_packets)
TX_PACKETS=$(cat /sys/class/net/$NETWORK_INTERFACE/statistics/tx_packets)
# Convert bytes to human readable
RX_MB=$((RX_BYTES / 1024 / 1024))
TX_MB=$((TX_BYTES / 1024 / 1024))
log_perf "NETWORK_STATS Interface: $NETWORK_INTERFACE, RX: ${RX_MB}MB (${RX_PACKETS} packets), TX: ${TX_MB}MB (${TX_PACKETS} packets)"
fi
# Docker Performance
if command -v docker >/dev/null 2>&1; then
cd {{ docker_compose_dir }}
log_perf "=== DOCKER PERFORMANCE ==="
# Docker system info
DOCKER_CONTAINERS_RUNNING=$(docker ps -q | wc -l)
DOCKER_CONTAINERS_TOTAL=$(docker ps -aq | wc -l)
DOCKER_IMAGES=$(docker images -q | wc -l)
log_perf "DOCKER_STATS Running containers: $DOCKER_CONTAINERS_RUNNING, Total containers: $DOCKER_CONTAINERS_TOTAL, Images: $DOCKER_IMAGES"
# Container resource usage
SERVICES=("sonarr" "radarr" "lidarr" "bazarr" "prowlarr" "watchtower")
for service in "${SERVICES[@]}"; do
CONTAINER_ID=$(docker-compose ps -q "$service" 2>/dev/null)
if [[ -n "$CONTAINER_ID" ]]; then
# Get container stats (single snapshot)
STATS=$(docker stats --no-stream --format "{{ '{{.CPUPerc}}' }}\t{{ '{{.MemUsage}}' }}\t{{ '{{.MemPerc}}' }}\t{{ '{{.NetIO}}' }}\t{{ '{{.BlockIO}}' }}" "$CONTAINER_ID" 2>/dev/null)
if [[ -n "$STATS" ]]; then
CPU_PERC=$(echo "$STATS" | cut -f1)
MEM_USAGE=$(echo "$STATS" | cut -f2)
MEM_PERC=$(echo "$STATS" | cut -f3)
NET_IO=$(echo "$STATS" | cut -f4)
BLOCK_IO=$(echo "$STATS" | cut -f5)
log_perf "CONTAINER_PERF $service - CPU: $CPU_PERC, Memory: $MEM_USAGE ($MEM_PERC), Network: $NET_IO, Disk: $BLOCK_IO"
fi
fi
done
# Docker system disk usage
DOCKER_SYSTEM_DF=$(docker system df --format "{{ '{{.Type}}' }}\t{{ '{{.TotalCount}}' }}\t{{ '{{.Active}}' }}\t{{ '{{.Size}}' }}\t{{ '{{.Reclaimable}}' }}" 2>/dev/null)
if [[ -n "$DOCKER_SYSTEM_DF" ]]; then
log_perf "DOCKER_DISK_USAGE:"
echo "$DOCKER_SYSTEM_DF" | while IFS=$'\t' read -r type total active size reclaimable; do
log_perf " $type - Total: $total, Active: $active, Size: $size, Reclaimable: $reclaimable"
done
fi
fi
# Process Information
log_perf "=== TOP PROCESSES ==="
TOP_PROCESSES=$(ps aux --sort=-%cpu | head -6 | tail -5)
echo "$TOP_PROCESSES" | while IFS= read -r line; do
log_perf "TOP_CPU $line"
done
TOP_MEMORY=$(ps aux --sort=-%mem | head -6 | tail -5)
echo "$TOP_MEMORY" | while IFS= read -r line; do
log_perf "TOP_MEM $line"
done
# I/O Statistics
if command -v iostat >/dev/null 2>&1; then
log_perf "=== I/O STATISTICS ==="
IOSTAT_OUTPUT=$(iostat -x 1 1 | tail -n +4)
echo "$IOSTAT_OUTPUT" | while IFS= read -r line; do
if [[ -n "$line" && "$line" != *"Device"* ]]; then
log_perf "IOSTAT $line"
fi
done
fi
# Performance Alerts
log_perf "=== PERFORMANCE ALERTS ==="
# CPU Alert (>80%)
if (( $(echo "$CPU_USAGE > 80" | bc -l) )); then
log_perf "ALERT_CPU High CPU usage: ${CPU_USAGE}%"
fi
# Memory Alert (>90%)
if (( $(echo "$MEMORY_PERCENT > 90" | bc -l) )); then
log_perf "ALERT_MEMORY High memory usage: ${MEMORY_PERCENT}%"
fi
# Disk Alert (>85%)
DISK_PERCENT_NUM=$(echo "$DISK_PERCENT" | cut -d'%' -f1)
if [[ $DISK_PERCENT_NUM -gt 85 ]]; then
log_perf "ALERT_DISK High disk usage: $DISK_PERCENT"
fi
# Load Average Alert (>2.0)
if (( $(echo "$LOAD_1MIN > 2.0" | bc -l) )); then
log_perf "ALERT_LOAD High load average: $LOAD_1MIN"
fi
log_perf "=== END PERFORMANCE MONITORING ==="
# Cleanup old performance logs (keep 7 days)
find "$LOG_DIR" -name "performance-*.log" -mtime +7 -delete 2>/dev/null
exit 0