- 📅 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