Files
FastapiAdmin/backend/app/core/logger.py
T
zhangtao 3f472d1e89 refactor: 重构存储与工作流模块,调整目录结构与初始化逻辑
1.  迁移存储模块功能到工作流模块,合并冗余代码
2.  调整环境配置加载路径与初始化脚本目录
3.  更新文档与前端组件代码适配重构
4.  新增工作流相关CRUD、模型与迁移文件
5.  移除过期模块与冗余代码,优化日志配置
2026-09-03 21:55:31 +08:00

91 lines
3.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import logging
import sys
from contextvars import ContextVar, Token
from loguru import logger
from app.common.enums import EnvironmentEnum
from app.config.path_conf import LOG_DIR
from app.config.setting import settings
# ── 请求链路 ID(日志追踪) ──
_correlation_id: ContextVar[str] = ContextVar("correlation_id", default="")
def set_correlation_id(cid: str) -> Token:
return _correlation_id.set(cid)
def get_correlation_id() -> str:
return _correlation_id.get()
def reset_correlation_id(token: Token) -> None:
_correlation_id.reset(token)
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]}"
_is_prod = settings.ENVIRONMENT == EnvironmentEnum.PROD
logger.add(sys.stdout, format=LOG_FMT, backtrace=not _is_prod, diagnose=not _is_prod, catch=True, level=settings.LOGGER_LEVEL)
logger.add(
sink=str(LOG_DIR / "fastapiadmin.log"),
format=LOG_FMT,
level=settings.LOGGER_LEVEL,
backtrace=not _is_prod,
diagnose=not _is_prod,
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", "alembic"]:
std = logging.getLogger(name)
std.handlers = [InterceptHandler()]
std.propagate = False
# 第三方库 DEBUG/INFO 噪音干扰太大,只保留 WARNING 以上:
# apscheduler(任务轮询)、alembic(autogenerate 插件注册 setup plugin、模型对比 Detected added 批量输出)、
# 数据库驱动(aiomysql 连接缓存、sqlalchemy 引擎日志,原 alembic.ini [logger_sqlalchemy] 的配置迁移至此)
for name in (
"apscheduler",
"apscheduler.schedulers",
"apscheduler.jobstores",
"alembic.autogenerate",
"alembic.runtime.plugins",
"sqlalchemy",
"aiomysql",
):
logging.getLogger(name).setLevel(logging.WARNING)
setup_logger()