auto-sync: 2026-05-22 18:29:36

This commit is contained in:
cfdaily
2026-05-22 18:29:36 +08:00
parent 06fc840325
commit df5d51ab0d
+41 -64
View File
@@ -4,22 +4,17 @@ set -euo pipefail
TARGET_DIR="$HOME/.sanguo_projects/sanguo_moziplus_v2" TARGET_DIR="$HOME/.sanguo_projects/sanguo_moziplus_v2"
PM2_NAME="sanguo-moziplus-v2" PM2_NAME="sanguo-moziplus-v2"
HEALTH_URL="http://localhost:8083/api/daemon/status"
DETAILED=false DETAILED=false
usage() { usage() {
echo "Usage: $0 [options]" echo "Usage: $0 [options]"
echo "" echo " -v, --verbose 显示详细信息"
echo "Options:"
echo " --target=DIR 安装目录"
echo " -v, --verbose 显示详细信息(项目列表、磁盘占用等)"
echo " -h, --help 显示帮助" echo " -h, --help 显示帮助"
exit 0 exit 0
} }
for arg in "$@"; do for arg in "$@"; do
case "$arg" in case "$arg" in
--target=*) TARGET_DIR="${arg#*=}" ;;
-v|--verbose) DETAILED=true ;; -v|--verbose) DETAILED=true ;;
-h|--help) usage ;; -h|--help) usage ;;
esac esac
@@ -30,8 +25,8 @@ echo " moziplus v2 — Status"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# ── 版本 ── # ── 版本 ──
VERSION=$(cd "$TARGET_DIR" 2>/dev/null && awk -F= '/^version/{gsub(/["'\''']/,"",$2); print $2}' pyproject.toml 2>/dev/null || echo unknown) VERSION=$(cd "$TARGET_DIR" 2>/dev/null && awk -F= '/^version/{gsub(/["'"'"']/,"",$2); print $2}' pyproject.toml 2>/dev/null || echo "unknown")
echo " Version: v$VERSION" echo " Version: v${VERSION}"
# ── 安装目录 ── # ── 安装目录 ──
if [ -d "$TARGET_DIR" ]; then if [ -d "$TARGET_DIR" ]; then
@@ -43,68 +38,47 @@ fi
# ── PM2 状态 ── # ── PM2 状态 ──
echo "" echo ""
PM2_STATUS=$(pm2 jlist 2>/dev/null | python3 -c " if pm2 describe "$PM2_NAME" >/dev/null 2>&1; then
import sys, json PM2_STATUS=$(pm2 describe "$PM2_NAME" 2>/dev/null)
procs = json.load(sys.stdin) STATUS=$(echo "$PM2_STATUS" | grep "status" | head -1 | awk '{print $NF}')
for p in procs: PID=$(echo "$PM2_STATUS" | grep "pid" | head -1 | awk '{print $NF}')
if p['name'] == '$PM2_NAME': UPTIME=$(echo "$PM2_STATUS" | grep "uptime" | head -1 | awk '{for(i=4;i<=NF;i++) printf $i" "; print ""}')
s = p['pm2_env']['status'] RESTARTS=$(echo "$PM2_STATUS" | grep "restart time" | awk '{print $NF}')
pid = p['pid'] or '-' MEM=$(echo "$PM2_STATUS" | grep "heap size" | head -1 | awk '{print $NF}')
uptime = p['pm2_env'].get('pm_uptime', 0) CPU=$(echo "$PM2_STATUS" | grep "cpu" | head -1 | awk '{print $NF}')
restarts = p['pm2_env'].get('restart_time', 0)
mem = p['monit'].get('memory', 0)
mem_mb = round(mem / 1024 / 1024, 1)
cpu = p['monit'].get('cpu', 0)
print(f'{s}|{pid}|{uptime}|{restarts}|{mem_mb}|{cpu}')
break
else:
print('not_found|||||')
" 2>/dev/null || echo 'error|||||')
IFS='|' read -r STATUS PID UPTIME RESTARTS MEM CPU <<< "$PM2_STATUS" if [ "$STATUS" = "online" ]; then
if [ "$STATUS" = "online" ]; then echo " PM2: online ✅"
# 计算 uptime
if [ -n "$UPTIME" ] && [ "$UPTIME" != "0" ]; then
UPTIME_FMT=$(python3 -c "
from datetime import datetime, timezone
delta = datetime.now(timezone.utc) - datetime.fromtimestamp($UPTIME/1000, tz=timezone.utc)
days = delta.days
hours, rem = divmod(delta.seconds, 3600)
mins, _ = divmod(rem, 60)
parts = []
if days: parts.append(f'{days}d')
if hours: parts.append(f'{hours}h')
parts.append(f'{mins}m')
print(' '.join(parts))
" 2>/dev/null || echo '?')
else else
UPTIME_FMT="just started" echo " PM2: $STATUS"
fi fi
echo " PM2: online ✅" echo " PID: ${PID:-?}"
echo " PID: $PID" echo " Uptime: ${UPTIME:-?}"
echo " Uptime: $UPTIME_FMT" echo " Restarts: ${RESTARTS:-0}"
echo " Restarts: $RESTARTS" echo " Memory: ${MEM:-?}"
echo " Memory: ${MEM}MB" echo " CPU: ${CPU:-?}%"
echo " CPU: ${CPU}%"
else else
echo " PM2: $STATUS ❌" echo " PM2: not found ❌"
fi fi
# ── 健康检查 ── # ── 健康检查 ──
echo "" echo ""
HEALTH=$(curl -sf "$HEALTH_URL" 2>/dev/null || echo '{"status":"unreachable"}') HEALTH=$(curl -sf http://localhost:8083/api/daemon/status 2>/dev/null || echo "")
HEALTH_STATUS=$(echo "$HEALTH" | python3 -c "import sys,json; print(json.load(sys.stdin).get('status','unknown'))" 2>/dev/null || echo 'unknown') if [ -n "$HEALTH" ]; then
if [ "$HEALTH_STATUS" = "ok" ]; then H_STATUS=$(echo "$HEALTH" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('status','?'))" 2>/dev/null || echo "?")
echo " Health: ok ✅" H_TICKS=$(echo "$HEALTH" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tick_count','?'))" 2>/dev/null || echo "?")
H_VERSION=$(echo "$HEALTH" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('version','?'))" 2>/dev/null || echo "?")
echo " Health: ${H_STATUS}"
echo " API ver: ${H_VERSION}"
echo " Ticks: ${H_TICKS}"
else else
echo " Health: $HEALTH_STATUS ❌" echo " Health: unreachable ❌"
fi fi
# ── 数据统计 ── # ── 数据统计 ──
echo "" echo ""
DATA_DIR="$TARGET_DIR/data" DATA_DIR="$TARGET_DIR/data"
if [ -d "$DATA_DIR" ]; then if [ -d "$DATA_DIR" ]; then
# 项目数
PROJ_COUNT=$(find "$DATA_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ') PROJ_COUNT=$(find "$DATA_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l | tr -d ' ')
DATA_SIZE=$(du -sh "$DATA_DIR" 2>/dev/null | cut -f1) DATA_SIZE=$(du -sh "$DATA_DIR" 2>/dev/null | cut -f1)
echo " Projects: $PROJ_COUNT" echo " Projects: $PROJ_COUNT"
@@ -117,8 +91,8 @@ if [ -d "$DATA_DIR" ]; then
proj_name=$(basename "$proj_dir") proj_name=$(basename "$proj_dir")
db_file="$proj_dir/blackboard.db" db_file="$proj_dir/blackboard.db"
if [ -f "$db_file" ]; then if [ -f "$db_file" ]; then
TASK_COUNT=$(sqlite3 "$db_file" "SELECT COUNT(*) FROM tasks" 2>/dev/null || echo '?') TASK_COUNT=$(sqlite3 "$db_file" "SELECT COUNT(*) FROM tasks" 2>/dev/null || echo "?")
ACTIVE_COUNT=$(sqlite3 "$db_file" "SELECT COUNT(*) FROM tasks WHERE status NOT IN ('done','cancelled','archived')" 2>/dev/null || echo '?') ACTIVE_COUNT=$(sqlite3 "$db_file" "SELECT COUNT(*) FROM tasks WHERE status NOT IN ('done','cancelled','archived')" 2>/dev/null || echo "?")
PROJ_SIZE=$(du -sh "$proj_dir" 2>/dev/null | cut -f1) PROJ_SIZE=$(du -sh "$proj_dir" 2>/dev/null | cut -f1)
printf " %-25s %s tasks (%s active) %s\n" "$proj_name" "$TASK_COUNT" "$ACTIVE_COUNT" "$PROJ_SIZE" printf " %-25s %s tasks (%s active) %s\n" "$proj_name" "$TASK_COUNT" "$ACTIVE_COUNT" "$PROJ_SIZE"
else else
@@ -131,13 +105,16 @@ fi
# ── 配置 ── # ── 配置 ──
if [ "$DETAILED" = true ]; then if [ "$DETAILED" = true ]; then
echo "" echo ""
echo " Config:" CONFIG_YAML="$TARGET_DIR/config/default.yaml"
PORT_VAL=$(grep -o 'port:.*' "$TARGET_DIR/config/default.yaml" 2>/dev/null | head -1) if [ -f "$CONFIG_YAML" ]; then
echo " Port: ${PORT_VAL:-8083 (default)}" echo " Config:"
INTERVAL_VAL=$(grep -o 'interval:.*' "$TARGET_DIR/config/default.yaml" 2>/dev/null | head -1) PORT_VAL=$(grep "port:" "$CONFIG_YAML" 2>/dev/null | head -1 | awk '{print $2}')
echo " Interval: ${INTERVAL_VAL:-30s}" INTERVAL_VAL=$(grep "interval:" "$CONFIG_YAML" 2>/dev/null | head -1 | awk '{print $2}')
AGENT_COUNT=$(grep 'agents:' -A 20 "$TARGET_DIR/config/default.yaml" 2>/dev/null | grep ' - ' | wc -l | tr -d ' ') AGENT_COUNT=$(grep " - " "$CONFIG_YAML" 2>/dev/null | wc -l | tr -d ' ')
echo " Agents: ${AGENT_COUNT:-0} configured" echo " Port: ${PORT_VAL:-8083}"
echo " Interval: ${INTERVAL_VAL:-30}"
echo " Agents: ${AGENT_COUNT:-0} configured"
fi
fi fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"