feat(logging): improve local and docker log handling
This commit is contained in:
@@ -15,6 +15,11 @@ if [ -f "$ROOT_DIR/.env" ]; then
|
||||
fi
|
||||
|
||||
BACKEND_HOST="${BACKEND_HOST:-0.0.0.0}"
|
||||
# 8800 是项目默认开发端口并由脚本独占;其他显式端口发生冲突时只报错。
|
||||
BACKEND_PORT_EXPLICIT=false
|
||||
if [ -n "${BACKEND_PORT+x}" ]; then
|
||||
BACKEND_PORT_EXPLICIT=true
|
||||
fi
|
||||
BACKEND_PORT="${BACKEND_PORT:-8800}"
|
||||
FRONTEND_HOST="${FRONTEND_HOST:-0.0.0.0}"
|
||||
FRONTEND_PORT="${FRONTEND_PORT:-5174}"
|
||||
@@ -40,7 +45,14 @@ DEV_YYB_WORKER_URL="${DEV_YYB_WORKER_URL:-http://127.0.0.1:${YYB_WORKER_PORT}}"
|
||||
YYB_WORKER_DATA_DIR="${YYB_WORKER_DATA_DIR:-$ROOT_DIR/data/yyb-worker-dev}"
|
||||
YYB_WORKER_NODE_MODULES="$ROOT_DIR/services/yyb-worker/node_modules"
|
||||
LOG_DIR="$ROOT_DIR/logs"
|
||||
APP_LOG="$LOG_DIR/app.log"
|
||||
APP_LOG="$LOG_DIR/app-$(date '+%Y-%m-%d').log"
|
||||
|
||||
# 本地一键启动始终写入项目内的持久化日志目录,避免与旧的 /Users/.../app.log 混淆。
|
||||
if [ "${1:-}" = "logs" ]; then
|
||||
mkdir -p "$LOG_DIR"
|
||||
echo "跟踪本地应用日志: ${APP_LOG}(Ctrl+C 退出)"
|
||||
exec tail -n "${LOG_TAIL_LINES:-200}" -F "$APP_LOG"
|
||||
fi
|
||||
|
||||
BACKEND_PID=""
|
||||
FRONTEND_PID=""
|
||||
@@ -92,13 +104,62 @@ detect_backend_proxy_host() {
|
||||
echo "$BACKEND_HOST"
|
||||
return
|
||||
fi
|
||||
# 绑定 0.0.0.0 时,Vite 代理不要固定连 127.0.0.1;某些本地工具会抢占 loopback 端口。
|
||||
local ip
|
||||
ip="$(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || true)"
|
||||
if [ -z "$ip" ] && command -v hostname >/dev/null 2>&1; then
|
||||
ip="$(hostname -I 2>/dev/null | awk '{print $1}' || true)"
|
||||
# Vite 是本机进程,回环代理最稳定;LAN 客户端仍可经 Vite 的 0.0.0.0 监听访问。
|
||||
echo "127.0.0.1"
|
||||
}
|
||||
|
||||
port_in_use() {
|
||||
command -v lsof >/dev/null 2>&1 && \
|
||||
lsof -nP -iTCP:"$1" -sTCP:LISTEN >/dev/null 2>&1
|
||||
}
|
||||
|
||||
show_port_owner() {
|
||||
lsof -nP -iTCP:"$1" -sTCP:LISTEN 2>/dev/null | awk 'NR == 2 {print " 占用进程: " $1 " (pid " $2 ")"}'
|
||||
}
|
||||
|
||||
ensure_backend_port_available() {
|
||||
if ! port_in_use "$BACKEND_PORT"; then
|
||||
return
|
||||
fi
|
||||
echo "${ip:-127.0.0.1}"
|
||||
# 本地开发默认端口由本项目独占;编辑器残留的端口转发会让健康检查命中错误进程。
|
||||
if [ "$BACKEND_PORT" = "8800" ]; then
|
||||
local pids pid
|
||||
pids="$(lsof -tiTCP:"$BACKEND_PORT" -sTCP:LISTEN 2>/dev/null || true)"
|
||||
echo "默认后端端口 $BACKEND_PORT 已被占用,正在停止占用进程..."
|
||||
show_port_owner "$BACKEND_PORT"
|
||||
for pid in $pids; do
|
||||
kill -TERM "$pid" 2>/dev/null || true
|
||||
done
|
||||
for _ in $(seq 1 5); do
|
||||
if ! port_in_use "$BACKEND_PORT"; then
|
||||
echo "端口 $BACKEND_PORT 已释放。"
|
||||
return
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
for pid in $pids; do
|
||||
kill -KILL "$pid" 2>/dev/null || true
|
||||
done
|
||||
sleep 1
|
||||
if ! port_in_use "$BACKEND_PORT"; then
|
||||
echo "端口 $BACKEND_PORT 已释放。"
|
||||
return
|
||||
fi
|
||||
echo "端口 $BACKEND_PORT 仍被占用,未启动后端。"
|
||||
show_port_owner "$BACKEND_PORT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$BACKEND_PORT_EXPLICIT" = true ]; then
|
||||
echo "后端端口 $BACKEND_PORT 已被占用,无法启动。"
|
||||
show_port_owner "$BACKEND_PORT"
|
||||
echo "请关闭占用程序,或在 .env 中设置一个空闲的 BACKEND_PORT 后重试。"
|
||||
exit 1
|
||||
fi
|
||||
echo "后端端口 $BACKEND_PORT 已被占用,无法启动。"
|
||||
show_port_owner "$BACKEND_PORT"
|
||||
echo "请在 .env 中设置空闲的 BACKEND_PORT 后重试。"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -n "${DATABASE_URL:-}" ] && [[ "$DATABASE_URL" != mysql+* ]]; then
|
||||
@@ -121,6 +182,8 @@ if [ -z "${YYB_WORKER_KEY:-}" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ensure_backend_port_available
|
||||
|
||||
COMPOSE=$(detect_compose)
|
||||
if [ -z "$COMPOSE" ]; then
|
||||
echo "缺少 docker compose"
|
||||
@@ -217,6 +280,7 @@ echo " MySQL: ${DB_HOST}:${DB_PORT}/${DB_NAME}"
|
||||
echo " YYB Worker: ${DEV_YYB_WORKER_URL}"
|
||||
echo " 数据库迁移: 已检查至最新版本"
|
||||
echo " 应用日志: ${APP_LOG}"
|
||||
echo " 跟踪日志: ./dev.sh logs"
|
||||
echo " 前端与 Worker 输出: 当前终端"
|
||||
echo " 退出: Ctrl+C"
|
||||
echo "=============================="
|
||||
@@ -225,7 +289,7 @@ echo ""
|
||||
(
|
||||
export DB_HOST DB_PORT DB_NAME DB_USER DB_PASSWORD
|
||||
export DB_POOL_SIZE DB_MAX_OVERFLOW DB_POOL_TIMEOUT DB_POOL_RECYCLE
|
||||
export YYB_WORKER_KEY LOG_LEVEL
|
||||
export YYB_WORKER_KEY LOG_LEVEL LOG_DIR
|
||||
export YYB_WORKER_URL="$DEV_YYB_WORKER_URL"
|
||||
uv run uvicorn web.backend.main:app \
|
||||
--host "$BACKEND_HOST" \
|
||||
@@ -237,6 +301,26 @@ echo ""
|
||||
) &
|
||||
BACKEND_PID=$!
|
||||
|
||||
echo "等待本地后端就绪..."
|
||||
for i in $(seq 1 20); do
|
||||
if curl -fsS --max-time 2 "http://127.0.0.1:${BACKEND_PORT}/api/health" 2>/dev/null | grep -q '"status":"ok"'; then
|
||||
echo "后端已就绪,日志持续写入: $APP_LOG"
|
||||
break
|
||||
fi
|
||||
if ! kill -0 "$BACKEND_PID" 2>/dev/null; then
|
||||
echo "后端启动失败,最近应用日志:"
|
||||
tail -n 80 "$APP_LOG" 2>/dev/null || true
|
||||
wait "$BACKEND_PID" || true
|
||||
exit 1
|
||||
fi
|
||||
if [ "$i" = "20" ]; then
|
||||
echo "后端启动超时,最近应用日志:"
|
||||
tail -n 80 "$APP_LOG" 2>/dev/null || true
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
(
|
||||
cd web/frontend
|
||||
VITE_BACKEND_TARGET="$BACKEND_PROXY_TARGET" \
|
||||
|
||||
Reference in New Issue
Block a user