feat(logging): improve local and docker log handling

This commit is contained in:
yml2213
2026-08-28 16:49:00 +08:00
parent 70621cff8f
commit 5ba70d5b4e
8 changed files with 348 additions and 47 deletions
+92 -8
View File
@@ -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" \