5250c2960c
- 解析 test_server -short 输出 (Rack/Cluster/Board/D0-D7) - 暗色主题仪表板: 逻辑板状态可视化、利用率、作业信息、T-Pod可用性 - 板级统计: 使用/空闲/离线, 利用率趋势图 (Chart.js) - collect.sh: Shell采集脚本(cron定时推送, 无需Python) - 历史快照管理: 查看详情/删除/清理 - systemd service 开机自启
110 lines
4.5 KiB
Bash
Executable File
110 lines
4.5 KiB
Bash
Executable File
#!/bin/bash
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# collect.sh — Palladium Z1 数据采集脚本 (Shell 版, 无需 Python)
|
|
#
|
|
# 在 Palladium 主机上运行, 执行 test_server -short 并推送到监控服务器
|
|
#
|
|
# 用法:
|
|
# ./collect.sh # 使用默认配置
|
|
# MONITOR_URL=http://10.0.0.1:5100/api/collect ./collect.sh
|
|
# TEST_SERVER_CMD="/edatools/vxe/VXE23.03.001/bin/test_server -short" ./collect.sh
|
|
# ./collect.sh --dry-run # 只采集不推送
|
|
#
|
|
# Crontab (每30分钟):
|
|
# */30 * * * * /path/to/collect.sh >> /var/log/palladium-collect.log 2>&1
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
# ─── 配置 (可通过环境变量覆盖) ───────────────────────────────
|
|
TEST_SERVER_CMD="${TEST_SERVER_CMD:-/edatools/vxe/VXE23.03.001/bin/test_server -short}"
|
|
MONITOR_URL="${MONITOR_URL:-http://10.168.1.209:5100/api/collect}"
|
|
TIMEOUT_SEC="${TIMEOUT_SEC:-300}"
|
|
LOG_PREFIX="[Palladium-Collect]"
|
|
|
|
# ─── 参数解析 ───────────────────────────────────────────────
|
|
DRY_RUN=false
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--dry-run) DRY_RUN=true; shift ;;
|
|
--help|-h)
|
|
head -18 "$0" | tail -15
|
|
exit 0 ;;
|
|
*) shift ;;
|
|
esac
|
|
done
|
|
|
|
# ─── 日志函数 ───────────────────────────────────────────────
|
|
log() { echo "$LOG_PREFIX $(date '+%Y-%m-%d %H:%M:%S') $*"; }
|
|
|
|
# ─── 执行采集 ───────────────────────────────────────────────
|
|
log "执行: $TEST_SERVER_CMD"
|
|
OUTPUT=$(timeout "$TIMEOUT_SEC" bash -c "$TEST_SERVER_CMD" 2>&1)
|
|
EXIT_CODE=$?
|
|
|
|
if [ $EXIT_CODE -ne 0 ]; then
|
|
log "[!] 命令退出码: $EXIT_CODE"
|
|
# test_server 可能输出 exit code != 0 但仍有有效输出, 继续处理
|
|
fi
|
|
|
|
if [ -z "$OUTPUT" ]; then
|
|
log "[!] 命令无输出, 跳过"
|
|
exit 1
|
|
fi
|
|
|
|
OUTPUT_LEN=${#OUTPUT}
|
|
log "采集成功, 输出 ${OUTPUT_LEN} 字节"
|
|
|
|
if [ "$DRY_RUN" = true ]; then
|
|
echo "──────────────────────────────────────────"
|
|
echo "$OUTPUT"
|
|
echo "──────────────────────────────────────────"
|
|
log "dry-run 模式, 不推送"
|
|
exit 0
|
|
fi
|
|
|
|
# ─── 推送到监控服务器 ───────────────────────────────────────
|
|
log "推送到: $MONITOR_URL"
|
|
|
|
# 用 python3 做 JSON 转义 (如果可用), 否则用 sed
|
|
if command -v python3 &>/dev/null; then
|
|
JSON_PAYLOAD=$(python3 -c "
|
|
import sys, json
|
|
print(json.dumps({'raw_output': sys.stdin.read(), 'source': 'cron'}))
|
|
" <<< "$OUTPUT")
|
|
else
|
|
# 简单转义 (无 python3 的后备方案)
|
|
ESCAPED=$(echo "$OUTPUT" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed ':a;N;$!ba;s/\n/\\n/g')
|
|
JSON_PAYLOAD="{\"raw_output\": \"$ESCAPED\", \"source\": \"cron\"}"
|
|
fi
|
|
|
|
HTTP_CODE=$(curl -s -o /tmp/palladium_resp.json -w "%{http_code}" \
|
|
-X POST "$MONITOR_URL" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$JSON_PAYLOAD" \
|
|
--connect-timeout 10 \
|
|
--max-time 30 2>/dev/null)
|
|
|
|
if [ "$HTTP_CODE" = "200" ]; then
|
|
RESP=$(cat /tmp/palladium_resp.json 2>/dev/null)
|
|
log "推送成功 — $(echo "$RESP" | grep -o '"snapshot_id":[0-9]*' | head -1)"
|
|
# 打印简要统计
|
|
if command -v python3 &>/dev/null; then
|
|
echo "$RESP" | python3 -c "
|
|
import sys, json
|
|
try:
|
|
d = json.load(sys.stdin)
|
|
s = d.get('stats', {})
|
|
if s:
|
|
print(f' 板: {s[\"total_boards\"]} (在线 {s[\"online_boards\"]}, 离线 {s[\"offline_boards\"]})')
|
|
print(f' 逻辑板: 利用率 {s[\"utilization\"]}% (使用 {s[\"used_boards\"]}/{s[\"total_boards\"]})')
|
|
print(f' 作业: {s[\"active_jobs\"]}')
|
|
except: pass
|
|
" 2>/dev/null
|
|
fi
|
|
else
|
|
log "[!] 推送失败: HTTP $HTTP_CODE"
|
|
cat /tmp/palladium_resp.json 2>/dev/null
|
|
exit 1
|
|
fi
|
|
|
|
rm -f /tmp/palladium_resp.json 2>/dev/null
|