优化日志与启动调试脚本

This commit is contained in:
yml2213
2026-08-12 16:29:37 +08:00
parent d19c0902f2
commit 03f5b8a6c4
2 changed files with 59 additions and 21 deletions
+32 -21
View File
@@ -40,9 +40,15 @@ YYB_WORKER_IMAGE="${YYB_WORKER_IMAGE:-douyu-yyb-worker:local}"
DEV_YYB_WORKER_URL="${DEV_YYB_WORKER_URL:-http://127.0.0.1:${YYB_WORKER_PORT}}"
YYB_WORKER_CONTAINER="${YYB_WORKER_CONTAINER:-douyu-yyb-worker-dev}"
YYB_WORKER_DATA_DIR="${YYB_WORKER_DATA_DIR:-$ROOT_DIR/data/yyb-worker-dev}"
LOG_DIR="$ROOT_DIR/logs"
LOG_DATE="$(date +%Y-%m-%d)"
BACKEND_LOG="$LOG_DIR/backend-$LOG_DATE.log"
FRONTEND_LOG="$LOG_DIR/frontend-$LOG_DATE.log"
WORKER_LOG="$LOG_DIR/yyb-worker-$LOG_DATE.log"
BACKEND_PID=""
FRONTEND_PID=""
WORKER_LOG_PID=""
WORKER_STARTED_BY_DEV=false
stop_tree() {
@@ -62,6 +68,7 @@ cleanup() {
trap - EXIT INT TERM
stop_tree "$FRONTEND_PID"
stop_tree "$BACKEND_PID"
stop_tree "$WORKER_LOG_PID"
if [ "$WORKER_STARTED_BY_DEV" = true ]; then
docker stop "$YYB_WORKER_CONTAINER" >/dev/null 2>&1 || true
fi
@@ -130,7 +137,7 @@ fi
BACKEND_PROXY_HOST="${BACKEND_PROXY_HOST:-$(detect_backend_proxy_host)}"
BACKEND_PROXY_TARGET="${VITE_BACKEND_TARGET:-http://${BACKEND_PROXY_HOST}:${BACKEND_PORT}}"
mkdir -p data logs
mkdir -p data "$LOG_DIR"
mkdir -p "$YYB_WORKER_DATA_DIR"
trap cleanup EXIT INT TERM
@@ -172,7 +179,14 @@ start_yyb_worker() {
done
}
stream_yyb_worker_logs() {
# docker logs 默认只输出到终端;持续转存后保留 Worker 的异常和协议脚本输出。
(docker logs --tail 100 --follow "$YYB_WORKER_CONTAINER" 2>&1 | tee -a "$WORKER_LOG") &
WORKER_LOG_PID=$!
}
start_yyb_worker
stream_yyb_worker_logs
echo "正在启动本地 MySQL..."
MYSQL_IMAGE="$MYSQL_IMAGE" \
@@ -203,35 +217,32 @@ echo " 前端: http://localhost:${FRONTEND_PORT}"
echo " API 代理: ${BACKEND_PROXY_TARGET}"
echo " MySQL: ${DB_HOST}:${DB_PORT}/${DB_NAME}"
echo " YYB Worker: ${DEV_YYB_WORKER_URL}"
echo " 后端日志: ${BACKEND_LOG}"
echo " 前端日志: ${FRONTEND_LOG}"
echo " Worker 日志: ${WORKER_LOG}"
echo " 退出: Ctrl+C"
echo "=============================="
echo ""
DB_HOST="$DB_HOST" \
DB_PORT="$DB_PORT" \
DB_NAME="$DB_NAME" \
DB_USER="$DB_USER" \
DB_PASSWORD="$DB_PASSWORD" \
DB_POOL_SIZE="$DB_POOL_SIZE" \
DB_MAX_OVERFLOW="$DB_MAX_OVERFLOW" \
DB_POOL_TIMEOUT="$DB_POOL_TIMEOUT" \
DB_POOL_RECYCLE="$DB_POOL_RECYCLE" \
YYB_WORKER_URL="$DEV_YYB_WORKER_URL" \
YYB_WORKER_KEY="$YYB_WORKER_KEY" \
LOG_LEVEL="$LOG_LEVEL" \
uv run uvicorn web.backend.main:app \
--host "$BACKEND_HOST" \
--port "$BACKEND_PORT" \
--reload \
--reload-dir core \
--reload-dir utils \
--reload-dir web/backend &
(
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_URL="$DEV_YYB_WORKER_URL"
uv run uvicorn web.backend.main:app \
--host "$BACKEND_HOST" \
--port "$BACKEND_PORT" \
--reload \
--reload-dir core \
--reload-dir utils \
--reload-dir web/backend 2>&1 | tee -a "$BACKEND_LOG"
) &
BACKEND_PID=$!
(
cd web/frontend
VITE_BACKEND_TARGET="$BACKEND_PROXY_TARGET" \
npm run dev -- --host "$FRONTEND_HOST" --port "$FRONTEND_PORT"
npm run dev -- --host "$FRONTEND_HOST" --port "$FRONTEND_PORT" 2>&1 | tee -a "$FRONTEND_LOG"
) &
FRONTEND_PID=$!
+27
View File
@@ -2,7 +2,9 @@
import os
import sys
import logging
from datetime import date
from logging.handlers import TimedRotatingFileHandler
from pathlib import Path
from loguru import logger
@@ -24,6 +26,30 @@ def _should_rotate(message, file):
return False
def _configure_standard_logging(level: str, log_dir: Path) -> None:
"""将 Uvicorn/FastAPI 的标准日志同步到控制台和文件。"""
log_level = getattr(logging, level.upper(), logging.INFO)
formatter = logging.Formatter(
"%(asctime)s | %(levelname)-8s | %(name)s | %(message)s"
)
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(log_level)
console_handler.setFormatter(formatter)
file_handler = TimedRotatingFileHandler(
log_dir / "server.log", when="midnight", backupCount=7, encoding="utf-8"
)
file_handler.setLevel(log_level)
file_handler.setFormatter(formatter)
for name in ("uvicorn", "uvicorn.error", "uvicorn.access", "fastapi", "starlette"):
standard_logger = logging.getLogger(name)
standard_logger.handlers = [console_handler, file_handler]
standard_logger.setLevel(log_level)
standard_logger.propagate = False
def setup_logger(level: str = "INFO", log_dir: str = None, log_file: str = None) -> None:
"""
配置日志
@@ -52,6 +78,7 @@ def setup_logger(level: str = "INFO", log_dir: str = None, log_file: str = None)
# 新接口:按目录 + 日期命名
dir_path = Path(log_dir)
dir_path.mkdir(parents=True, exist_ok=True)
_configure_standard_logging(level, dir_path)
file_path = str(dir_path / "app-{time:YYYY-MM-DD}.log")
elif log_file:
# 兼容旧接口