Fix edge to handle nested metrics format from gateway forwarding

This commit is contained in:
buenosairesam
2026-01-26 20:36:34 -03:00
parent 754d3e55fb
commit 2da4b30019
5 changed files with 100 additions and 6 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
def
.env
ctrl/.env

3
ctrl/.env.example Normal file
View File

@@ -0,0 +1,3 @@
EDGE_URL=wss://sysmonstm.mcrn.ar/ws
EDGE_API_KEY=your-api-key-here
MACHINE_ID=your-hostname

46
ctrl/collector.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/bin/bash
# Run sysmonstm collector only (for secondary machines)
# Usage: ./ctrl/collector.sh [aggregator-ip] [--remote]
#
# Examples:
# ./ctrl/collector.sh 192.168.1.33 # Build locally (default)
# ./ctrl/collector.sh 192.168.1.33 --remote # Use registry image
cd "$(dirname "$0")/.."
AGGREGATOR_IP=${1:-192.168.1.33}
MACHINE_ID=$(hostname)
USE_REMOTE=false
if [ "$2" = "--remote" ]; then
USE_REMOTE=true
fi
# Check if aggregator is reachable
echo "Checking connection to aggregator at $AGGREGATOR_IP:50051..."
if ! nc -z -w 3 "$AGGREGATOR_IP" 50051 2>/dev/null; then
echo ""
echo "ERROR: Cannot connect to aggregator at $AGGREGATOR_IP:50051"
echo ""
echo "Make sure the full stack is running on the main machine first:"
echo " cd ~/wdir/sms && ./ctrl/run.sh"
echo ""
exit 1
fi
echo "Aggregator reachable."
if [ "$USE_REMOTE" = true ]; then
IMAGE="registry.mcrn.ar/sysmonstm/collector:latest"
echo "Using remote image: $IMAGE"
else
IMAGE="sysmonstm-collector:local"
echo "Building local image..."
docker build -t $IMAGE -f services/collector/Dockerfile .
fi
echo "Starting collector for $MACHINE_ID -> $AGGREGATOR_IP:50051"
docker run --rm --name sysmonstm-collector --network host \
-e AGGREGATOR_URL=${AGGREGATOR_IP}:50051 \
-e MACHINE_ID=${MACHINE_ID} \
$IMAGE

View File

@@ -222,16 +222,37 @@ async def websocket_endpoint(websocket: WebSocket, key: str = Query(default=""))
await websocket.close(code=4001, reason="Invalid API key")
return
machine_id = data.get("machine_id", "unknown")
machines[machine_id] = data
log.debug(f"Metrics from {machine_id}: cpu={data.get('cpu')}%")
# Handle both formats:
# 1. Direct: {"type": "metrics", "machine_id": "...", "cpu": ...}
# 2. Nested (from gateway): {"type": "metrics", "data": {...}, "timestamp": "..."}
if "data" in data and isinstance(data["data"], dict):
# Nested format from gateway forwarding
payload = data["data"]
machine_id = payload.get("machine_id", "unknown")
# Extract metrics from nested structure
metrics = payload.get("metrics", {})
metric_data = {
"type": "metrics",
"machine_id": machine_id,
"hostname": payload.get("hostname", ""),
"timestamp": data.get("timestamp"),
}
# Flatten metrics for dashboard display
for key_name, value in metrics.items():
metric_data[key_name.lower()] = value
machines[machine_id] = metric_data
log.debug(f"Metrics (forwarded) from {machine_id}")
else:
# Direct format from collector
machine_id = data.get("machine_id", "unknown")
machines[machine_id] = data
log.debug(f"Metrics from {machine_id}: cpu={data.get('cpu')}%")
# Broadcast to all connected clients
broadcast_data = machines[machine_id]
for conn in connections:
try:
await conn.send_json(
{"type": "metrics", "machine_id": machine_id, **data}
)
await conn.send_json(broadcast_data)
except Exception:
pass

23
ctrl/run.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
# Run sysmonstm full stack locally with edge forwarding
# Usage: ./ctrl/run.sh [--remote]
#
# Examples:
# ./ctrl/run.sh # Build locally (default)
# ./ctrl/run.sh --remote # Use registry images
cd "$(dirname "$0")/.."
# Load env from ctrl/.env
set -a
source ctrl/.env
set +a
if [ "$1" = "--remote" ]; then
echo "Using remote images from registry"
docker compose pull
docker compose up "${@:2}"
else
echo "Building locally..."
docker compose up --build "$@"
fi