Files
FastapiAdmin/backend/app/core/logger.py
T
zhangtao cf88ab8897 refactor: 整合仪表盘功能到监控模块,清理冗余代码
- 移除原监控仪表盘独立模块,将相关功能合并到在线监控模块
- 重构租户配置字段名,统一使用logo_url和name替代tenant_logo/tenant_name
- 优化搜索工具函数,移除重复导入
- 调整参数配置模型字段长度限制,移除config_value的max_length约束
- 清理冗余的常量定义和导入语句
- 修复批量状态设置接口的redis依赖注入
- 增强OAuth登录安全性,添加租户默认归属和state一次性消费
- 优化资源目录缓存逻辑,减少重复计算
- 新增API Token模块基础框架
- 完善用户token版本管理,支持主动失效JWT
- 调整AI模型配置缓存过期时间
- 修复菜单类型字段索引,提升查询性能
- 简化前端刷新token调用逻辑
- 新增滑块验证完成接口和忘记密码验证码校验
- 调整系统配置默认值,添加操作日志保留天数和接口白名单配置
- 限制Mock支付回调仅在开发环境可用
- 重构websocket认证方式,支持更安全的subprotocol传参
2026-07-13 01:14:20 +08:00

63 lines
2.2 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):
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
# APScheduler 的 DEBUG 轮询日志干扰太大,只保留 WARNING 以上
for name in ("apscheduler", "apscheduler.schedulers", "apscheduler.jobstores"):
logging.getLogger(name).setLevel(logging.WARNING)
setup_logger()