mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-22 13:05:18 +00:00
此提交包含多项核心优化: 1. 依赖库升级:更新FastAPI、替换fastapi-limiter为slowapi,更换MySQL驱动为aiomysql,重构缓存系统使用fastapi-cache2-fork 2. 代码重构:移除自定义缓存工具,统一使用fastapi-cache2;重构请求限流逻辑,修复操作日志记录开关逻辑 3. 接口规范:统一将Depends分页/查询参数改为Query注解,补全File上传依赖注解 4. 前端优化:调整登录滑块进度条颜色、移除冗余demo页面样式类 5. 日志优化:重构日志配置,使用time.perf_counter替代time.time统计耗时 6. 测试优化:移除冗余的限流mock配置,改用官方限流方案 7. 模板优化:更新vue代码生成模板,移除冗余导入并优化组件使用 8. 导入功能优化:移除pandas依赖,使用Excel工具类重构文件导入逻辑
72 lines
2.1 KiB
Python
72 lines
2.1 KiB
Python
import logging
|
|
import sys
|
|
|
|
from loguru import logger
|
|
|
|
from app.config.path_conf import LOG_DIR
|
|
from app.config.setting import settings
|
|
from app.core.request_context import get_correlation_id
|
|
|
|
|
|
def _context_patcher(record: dict) -> None:
|
|
cid = get_correlation_id()
|
|
record["extra"]["ctx"] = f" | cid={cid[:8]}" if cid else ""
|
|
|
|
|
|
class InterceptHandler(logging.Handler):
|
|
"""将标准库 logging 重定向到 Loguru"""
|
|
|
|
def emit(self, record: logging.LogRecord) -> None:
|
|
try:
|
|
level = logger.level(record.levelname).name
|
|
except ValueError:
|
|
level = record.levelno
|
|
frame, depth = logging.currentframe(), 2
|
|
while frame and frame.f_code.co_filename == logging.__file__:
|
|
frame = frame.f_back
|
|
depth += 1
|
|
logger.opt(depth=depth, exception=record.exc_info).log(level, "{}", record.getMessage())
|
|
|
|
|
|
def setup_logger() -> None:
|
|
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
|
logger.remove()
|
|
logger.configure(patcher=_context_patcher)
|
|
|
|
LOG_FMT = (
|
|
"<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | "
|
|
"<level>{level: <8}</level> | "
|
|
"<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - "
|
|
"<level>{message}</level>"
|
|
"{extra[ctx]}"
|
|
)
|
|
logger.add(
|
|
sys.stdout,
|
|
format=LOG_FMT,
|
|
backtrace=True,
|
|
diagnose=True,
|
|
catch=True,
|
|
level=settings.LOGGER_LEVEL
|
|
)
|
|
logger.add(
|
|
sink=str(LOG_DIR / "fastapiadmin.log"),
|
|
format=LOG_FMT,
|
|
level=settings.LOGGER_LEVEL,
|
|
backtrace=True,
|
|
diagnose=True,
|
|
catch=True,
|
|
rotation="00:00",
|
|
retention=30,
|
|
compression="gz",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
logging.basicConfig(handlers=[InterceptHandler()], level=settings.LOGGER_LEVEL, force=True)
|
|
for name in [k for k in logging.root.manager.loggerDict if isinstance(k, str)] + ["uvicorn", "uvicorn.error", "uvicorn.access"]:
|
|
std = logging.getLogger(name)
|
|
std.handlers = [InterceptHandler()]
|
|
std.propagate = False
|
|
|
|
|
|
setup_logger()
|