#!/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