#!/bin/bash # Monitor I2P router health endpoint during live test. # Polls every 30 seconds, writes timestamped JSON to a log file. # Usage: bash tools/monitor_router.sh [duration_minutes] [interval_seconds] DURATION_MIN=${1:-60} INTERVAL_SEC=${2:-30} LOG_FILE="$(dirname "$0")/router_monitor.log" HEALTH_URL="http://localhost:9701" TOTAL_POLLS=$(( DURATION_MIN * 60 / INTERVAL_SEC )) echo "=== I2P Router Monitor ===" | tee "$LOG_FILE" echo "Started: $(date -Iseconds)" | tee -a "$LOG_FILE" echo "Duration: ${DURATION_MIN}min, Interval: ${INTERVAL_SEC}s, Polls: ${TOTAL_POLLS}" | tee -a "$LOG_FILE" echo "---" | tee -a "$LOG_FILE" for i in $(seq 1 $TOTAL_POLLS); do TS=$(date -Iseconds) RESPONSE=$(curl -s --max-time 5 "$HEALTH_URL" 2>&1) EXIT_CODE=$? if [ $EXIT_CODE -ne 0 ]; then echo "[$TS] poll=$i CURL_FAILED exit=$EXIT_CODE" | tee -a "$LOG_FILE" else # Extract key fields for the summary line STATE=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('state','?'))" 2>/dev/null) UPTIME=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('uptime_seconds',0))" 2>/dev/null) PEERS=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('peer_count',0))" 2>/dev/null) ATTEMPTED=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('peers_attempted',0))" 2>/dev/null) SUCCESSFUL=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('peers_successful',0))" 2>/dev/null) FAILED=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('peers_failed',0))" 2>/dev/null) NETDB=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('netdb_routerinfos',0))" 2>/dev/null) NETDB_DISK=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('netdb_disk',0))" 2>/dev/null) RSS=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('resources',{}).get('rss_mb',0))" 2>/dev/null) CPU=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('resources',{}).get('cpu_percent','?'))" 2>/dev/null) I2NP_RX=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('i2np_messages_received',0))" 2>/dev/null) I2NP_TX=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('i2np_messages_sent',0))" 2>/dev/null) echo "[$TS] poll=$i state=$STATE uptime=${UPTIME}s peers=$PEERS attempted=$ATTEMPTED ok=$SUCCESSFUL fail=$FAILED netdb=$NETDB disk=$NETDB_DISK rss=${RSS}MB cpu=${CPU}% i2np_rx=$I2NP_RX i2np_tx=$I2NP_TX" | tee -a "$LOG_FILE" # Write full JSON every 5th poll for detailed analysis if [ $(( i % 5 )) -eq 0 ]; then echo " FULL_JSON: $RESPONSE" >> "$LOG_FILE" fi fi # Check if container is still running if ! podman ps --filter name=i2p-router-test --format "{{.Status}}" | grep -q "Up"; then echo "[$TS] CONTAINER STOPPED — aborting monitor" | tee -a "$LOG_FILE" echo "Last container logs:" | tee -a "$LOG_FILE" podman logs --tail 20 i2p-router-test 2>&1 | tee -a "$LOG_FILE" break fi sleep $INTERVAL_SEC done echo "---" | tee -a "$LOG_FILE" echo "Finished: $(date -Iseconds)" | tee -a "$LOG_FILE" echo "Final health:" | tee -a "$LOG_FILE" curl -s --max-time 5 "$HEALTH_URL" 2>&1 | python3 -m json.tool 2>&1 | tee -a "$LOG_FILE"