📅 2025-07-06T15:25:32.072Z
👁️ 53 katselukertaa
🔓 Julkinen


#!/bin/bash

# Real-time Proxy Server Metrics Script
# Usage: ./metrics.sh [--loop] [--interval seconds]

LOOP=false
INTERVAL=3
INTERFACE=$(ip route | grep default | awk '{print $5}' | head -1)

# Parse arguments
while [[ $# -gt 0 ]]; do
    case $1 in
        --loop)
            LOOP=true
            shift
            ;;
        --interval)
            INTERVAL="$2"
            shift 2
            ;;
        *)
            echo "Usage: $0 [--loop] [--interval seconds]"
            exit 1
            ;;
    esac
done

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'

# Helper functions
timestamp() {
    date '+%Y-%m-%d %H:%M:%S'
}

format_bytes() {
    local bytes=$1
    if [ $bytes -gt 1073741824 ]; then
        printf "%.2f GB" $(echo "scale=2; $bytes/1073741824" | bc)
    elif [ $bytes -gt 1048576 ]; then
        printf "%.2f MB" $(echo "scale=2; $bytes/1048576" | bc)
    elif [ $bytes -gt 1024 ]; then
        printf "%.2f KB" $(echo "scale=2; $bytes/1024" | bc)
    else
        printf "%d B" $bytes
    fi
}

format_number() {
    printf "%'d" $1 2>/dev/null || printf "%d" $1
}

status_color() {
    local value=$1
    local warn=${2:-70}
    local crit=${3:-90}
    
    if (( $(echo "$value >= $crit" | bc -l) )); then
        echo "$RED"
    elif (( $(echo "$value >= $warn" | bc -l) )); then
        echo "$YELLOW"
    else
        echo "$GREEN"
    fi
}

get_metrics() {
    local timestamp=$(timestamp)
    
    echo -e "${BOLD}${BLUE}=================== PROXY METRICS ====================${NC}"
    echo -e "${CYAN}Timestamp: $timestamp${NC}"
    echo -e "${CYAN}Interface: $INTERFACE${NC}"
    echo ""
    
    # === SYSTEM MEMORY ===
    echo -e "${BOLD}${YELLOW}MEMORY USAGE:${NC}"
    local mem_info=$(free -b)
    local mem_line=$(echo "$mem_info" | grep "Mem:")
    local swap_line=$(echo "$mem_info" | grep "Swap:")
    
    local total_mem=$(echo $mem_line | awk '{print $2}')
    local used_mem=$(echo $mem_line | awk '{print $3}')
    local avail_mem=$(echo $mem_line | awk '{print $7}')
    local mem_percent=$(echo "scale=1; $used_mem * 100 / $total_mem" | bc)
    local mem_color=$(status_color $mem_percent)
    
    echo -e "  RAM Usage:    ${mem_color}${mem_percent}%${NC} ($(format_bytes $used_mem) / $(format_bytes $total_mem))"
    echo -e "  Available:    $(format_bytes $avail_mem)"
    
    if [ ! -z "$swap_line" ]; then
        local total_swap=$(echo $swap_line | awk '{print $2}')
        local used_swap=$(echo $swap_line | awk '{print $3}')
        if [ $total_swap -gt 0 ]; then
            local swap_percent=$(echo "scale=1; $used_swap * 100 / $total_swap" | bc)
            local swap_color=$(status_color $swap_percent)
            echo -e "  Swap Usage:   ${swap_color}${swap_percent}%${NC} ($(format_bytes $used_swap) / $(format_bytes $total_swap))"
        fi
    fi
    
    # === 3PROXY PROCESS ===
    echo ""
    echo -e "${BOLD}${YELLOW}3PROXY PROCESS:${NC}"
    local proxy_pid=$(pgrep 3proxy)
    
    if [ ! -z "$proxy_pid" ]; then
        local proxy_status=$(cat /proc/$proxy_pid/status 2>/dev/null)
        if [ $? -eq 0 ]; then
            local threads=$(echo "$proxy_status" | grep "^Threads:" | awk '{print $2}')
            local vmsize_kb=$(echo "$proxy_status" | grep "^VmSize:" | awk '{print $2}')
            local vmrss_kb=$(echo "$proxy_status" | grep "^VmRSS:" | awk '{print $2}')
            local vmstk_kb=$(echo "$proxy_status" | grep "^VmStk:" | awk '{print $2}')
            
            local vmsize_bytes=$((vmsize_kb * 1024))
            local vmrss_bytes=$((vmrss_kb * 1024))
            local vmstk_bytes=$((vmstk_kb * 1024))
            
            local thread_color=$(status_color $(echo "scale=1; $threads / 1000" | bc) 50 80)
            
            echo -e "  PID:          $proxy_pid"
            echo -e "  Threads:      ${thread_color}$(format_number $threads)${NC}"
            echo -e "  Virtual Mem:  $(format_bytes $vmsize_bytes)"
            echo -e "  Physical Mem: $(format_bytes $vmrss_bytes)"
            echo -e "  Stack Usage:  $(format_bytes $vmstk_bytes)"
            
            # CPU usage
            local cpu_percent=$(ps -p $proxy_pid -o %cpu --no-headers | tr -d ' ')
            local cpu_color=$(status_color $cpu_percent 80 95)
            echo -e "  CPU Usage:    ${cpu_color}${cpu_percent}%${NC}"
        fi
    else
        echo -e "  ${RED}3PROXY NOT RUNNING!${NC}"
    fi
    
    # === NETWORK CONNECTIONS ===
    echo ""
    echo -e "${BOLD}${YELLOW}NETWORK CONNECTIONS:${NC}"
    local ss_output=$(ss -s)
    
    # Parse ss output
    local total_sockets=$(echo "$ss_output" | grep "^Total:" | grep -oE '[0-9]+' | head -1)
    local tcp_line=$(echo "$ss_output" | grep "^TCP:")
    
    if [ ! -z "$tcp_line" ]; then
        local tcp_total=$(echo "$tcp_line" | grep -oE 'TCP:\s+[0-9]+' | grep -oE '[0-9]+')
        local tcp_estab=$(echo "$tcp_line" | grep -oE 'estab [0-9]+' | awk '{print $2}')
        local tcp_closed=$(echo "$tcp_line" | grep -oE 'closed [0-9]+' | awk '{print $2}')
        local tcp_orphaned=$(echo "$tcp_line" | grep -oE 'orphaned [0-9]+' | awk '{print $2}')
        local tcp_timewait=$(echo "$tcp_line" | grep -oE 'timewait [0-9]+' | awk '{print $2}')
        
        local conn_color=$(status_color $(echo "scale=1; ${tcp_estab:-0} / 1000" | bc) 100 200)
        local orphan_color=$(status_color $(echo "scale=1; ${tcp_orphaned:-0} / 100" | bc) 50 100)
        
        echo -e "  Total TCP:    $(format_number ${tcp_total:-0})"
        echo -e "  Established:  ${conn_color}$(format_number ${tcp_estab:-0})${NC}"
        echo -e "  Closed:       $(format_number ${tcp_closed:-0})"
        echo -e "  Orphaned:     ${orphan_color}$(format_number ${tcp_orphaned:-0})${NC}"
        echo -e "  TIME_WAIT:    $(format_number ${tcp_timewait:-0})"
    fi
    
    # === FILE DESCRIPTORS ===
    echo ""
    echo -e "${BOLD}${YELLOW}FILE DESCRIPTORS:${NC}"
    local fd_info=$(cat /proc/sys/fs/file-nr)
    local open_fds=$(echo $fd_info | awk '{print $1}')
    local max_fds=$(echo $fd_info | awk '{print $3}')
    local fd_percent=$(echo "scale=1; $open_fds * 100 / $max_fds" | bc)
    local fd_color=$(status_color $fd_percent 70 85)
    
    echo -e "  Open FDs:     ${fd_color}${fd_percent}%${NC} ($(format_number $open_fds) / $(format_number $max_fds))"
    
    # === KERNEL LIMITS ===
    echo ""
    echo -e "${BOLD}${YELLOW}KERNEL LIMITS:${NC}"
    local threads_max=$(cat /proc/sys/kernel/threads-max 2>/dev/null || echo "unknown")
    local pid_max=$(cat /proc/sys/kernel/pid_max 2>/dev/null || echo "unknown")
    local total_threads=$(ps -eLf 2>/dev/null | wc -l)
    
    if [ "$threads_max" != "unknown" ]; then
        local thread_percent=$(echo "scale=1; $total_threads * 100 / $threads_max" | bc)
        local thread_limit_color=$(status_color $thread_percent 60 80)
        echo -e "  System Threads: ${thread_limit_color}${thread_percent}%${NC} ($(format_number $total_threads) / $(format_number $threads_max))"
    else
        echo -e "  System Threads: $(format_number $total_threads)"
    fi
    echo -e "  Max PIDs:     $(format_number $pid_max)"
    
    # === BANDWIDTH MONITORING ===
    echo ""
    echo -e "${BOLD}${YELLOW}NETWORK INTERFACE ($INTERFACE):${NC}"
    
    if [ -f "/sys/class/net/$INTERFACE/statistics/rx_bytes" ]; then
        local rx_bytes=$(cat /sys/class/net/$INTERFACE/statistics/rx_bytes)
        local tx_bytes=$(cat /sys/class/net/$INTERFACE/statistics/tx_bytes)
        local rx_packets=$(cat /sys/class/net/$INTERFACE/statistics/rx_packets)
        local tx_packets=$(cat /sys/class/net/$INTERFACE/statistics/tx_packets)
        local rx_dropped=$(cat /sys/class/net/$INTERFACE/statistics/rx_dropped)
        local tx_dropped=$(cat /sys/class/net/$INTERFACE/statistics/tx_dropped)
        local rx_errors=$(cat /sys/class/net/$INTERFACE/statistics/rx_errors)
        local tx_errors=$(cat /sys/class/net/$INTERFACE/statistics/tx_errors)
        
        echo -e "  RX Total:     $(format_bytes $rx_bytes) ($(format_number $rx_packets) packets)"
        echo -e "  TX Total:     $(format_bytes $tx_bytes) ($(format_number $tx_packets) packets)"
        
        if [ $((rx_dropped + tx_dropped + rx_errors + tx_errors)) -gt 0 ]; then
            echo -e "  ${RED}Issues:${NC}"
            [ $rx_dropped -gt 0 ] && echo -e "    RX Dropped: $(format_number $rx_dropped)"
            [ $tx_dropped -gt 0 ] && echo -e "    TX Dropped: $(format_number $tx_dropped)"
            [ $rx_errors -gt 0 ] && echo -e "    RX Errors:  $(format_number $rx_errors)"
            [ $tx_errors -gt 0 ] && echo -e "    TX Errors:  $(format_number $tx_errors)"
        else
            echo -e "  ${GREEN}No packet drops or errors${NC}"
        fi
    else
        echo -e "  ${RED}Interface statistics not available${NC}"
    fi
    
    # === DNS STATUS ===
    echo ""
    echo -e "${BOLD}${YELLOW}DNS STATUS:${NC}"
    local dns_start=$(date +%s%N)
    local dns_result=$(timeout 3 dig @1.1.1.1 google.com +short 2>/dev/null)
    local dns_end=$(date +%s%N)
    
    if [ $? -eq 0 ] && [ ! -z "$dns_result" ]; then
        local dns_time=$(echo "scale=0; ($dns_end - $dns_start) / 1000000" | bc)
        echo -e "  DNS Status:   ${GREEN}OK${NC} (${dns_time}ms)"
    else
        echo -e "  DNS Status:   ${RED}FAILED${NC}"
    fi
    
    # === SYSTEM LOAD ===
    echo ""
    echo -e "${BOLD}${YELLOW}SYSTEM LOAD:${NC}"
    local load_avg=$(cat /proc/loadavg | awk '{print $1, $2, $3}')
    local cpu_count=$(nproc)
    local load_1min=$(echo $load_avg | awk '{print $1}')
    local load_percent=$(echo "scale=1; $load_1min * 100 / $cpu_count" | bc)
    local load_color=$(status_color $load_percent 70 90)
    
    echo -e "  Load Average: ${load_color}$load_avg${NC} (${cpu_count} cores)"
    echo -e "  Load %:       ${load_color}${load_percent}%${NC}"
    
    # === DISK USAGE ===
    echo ""
    echo -e "${BOLD}${YELLOW}DISK USAGE (root):${NC}"
    local disk_info=$(df / | tail -1)
    local disk_used=$(echo $disk_info | awk '{print $5}' | sed 's/%//')
    local disk_color=$(status_color $disk_used 80 90)
    local disk_avail=$(echo $disk_info | awk '{print $4}')
    
    echo -e "  Usage:        ${disk_color}${disk_used}%${NC}"
    echo -e "  Available:    $(format_bytes $((disk_avail * 1024)))"
    
    echo -e "${BOLD}${BLUE}====================================================${NC}"
}

# Bandwidth calculation function (for loop mode)
calculate_bandwidth() {
    local interface=$1
    local prev_rx=$2
    local prev_tx=$3
    local interval=$4
    
    if [ -f "/sys/class/net/$interface/statistics/rx_bytes" ]; then
        local curr_rx=$(cat /sys/class/net/$interface/statistics/rx_bytes)
        local curr_tx=$(cat /sys/class/net/$interface/statistics/tx_bytes)
        
        if [ ! -z "$prev_rx" ] && [ ! -z "$prev_tx" ]; then
            local rx_rate=$(echo "($curr_rx - $prev_rx) / $interval" | bc)
            local tx_rate=$(echo "($curr_tx - $prev_tx) / $interval" | bc)
            local rx_mbps=$(echo "scale=2; $rx_rate * 8 / 1000000" | bc)
            local tx_mbps=$(echo "scale=2; $tx_rate * 8 / 1000000" | bc)
            local total_mbps=$(echo "scale=2; $rx_mbps + $tx_mbps" | bc)
            
            echo ""
            echo -e "${BOLD}${YELLOW}CURRENT BANDWIDTH:${NC}"
            echo -e "  Download:     ${rx_mbps} Mbps ($(format_bytes $rx_rate)/s)"
            echo -e "  Upload:       ${tx_mbps} Mbps ($(format_bytes $tx_rate)/s)"
            echo -e "  Total:        ${total_mbps} Mbps"
            
            # Utilization assuming 1Gbps link
            local util_percent=$(echo "scale=1; $total_mbps * 100 / 1000" | bc)
            local util_color=$(status_color $util_percent 70 90)
            echo -e "  Utilization:  ${util_color}${util_percent}%${NC} (of 1Gbps)"
        fi
        
        echo "$curr_rx,$curr_tx"
    else
        echo "0,0"
    fi
}

# Main execution
if [ "$LOOP" = true ]; then
    echo "Starting continuous monitoring (Ctrl+C to stop)..."
    echo "Update interval: ${INTERVAL}s"
    echo ""
    
    prev_net_stats=""
    
    while true; do
        clear
        get_metrics
        
        # Get network stats for bandwidth calculation
        if [ -f "/sys/class/net/$INTERFACE/statistics/rx_bytes" ]; then
            curr_net_stats=$(calculate_bandwidth "$INTERFACE" \
                "$(echo $prev_net_stats | cut -d, -f1)" \
                "$(echo $prev_net_stats | cut -d, -f2)" \
                "$INTERVAL")
            prev_net_stats="$(echo $curr_net_stats | tail -1)"
        fi
        
        echo ""
        echo -e "${CYAN}Next update in ${INTERVAL}s... (Ctrl+C to stop)${NC}"
        sleep $INTERVAL
    done
else
    get_metrics
fi