102 lines
2.8 KiB
Python
102 lines
2.8 KiB
Python
# ===========================================
|
||
# 班级操行分管理系统 - 后端服务
|
||
#
|
||
# 开发者: Canglan
|
||
# 联系方式: admin@sea-studio.top
|
||
# 版权归属: Sea Network Technology Studio
|
||
# 许可证: MIT License
|
||
#
|
||
# 版权所有 © Sea Network Technology Studio
|
||
# ===========================================
|
||
|
||
import sys
|
||
from loguru import logger
|
||
from pathlib import Path
|
||
from fastapi import Request
|
||
|
||
from config import settings
|
||
|
||
|
||
# 日志目录
|
||
LOG_DIR = Path(__file__).parent.parent / "logs"
|
||
LOG_DIR.mkdir(exist_ok=True)
|
||
|
||
|
||
def setup_logger():
|
||
"""配置日志系统"""
|
||
|
||
# 移除默认处理器
|
||
logger.remove()
|
||
|
||
# 控制台输出(仅INFO及以上)
|
||
logger.add(
|
||
sys.stdout,
|
||
format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level: <8}</level> | <cyan>{name}</cyan> - <level>{message}</level>",
|
||
level=settings.LOG_LEVEL,
|
||
colorize=True
|
||
)
|
||
|
||
# 应用日志(轮转)
|
||
logger.add(
|
||
LOG_DIR / "app.log",
|
||
format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name} | {message}",
|
||
rotation=settings.LOG_MAX_BYTES,
|
||
retention=settings.LOG_RETENTION_DAYS,
|
||
compression="gz",
|
||
encoding="utf-8",
|
||
level="DEBUG"
|
||
)
|
||
|
||
# 错误日志(单独记录)
|
||
logger.add(
|
||
LOG_DIR / "error.log",
|
||
format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name} | {message}",
|
||
rotation=settings.LOG_MAX_BYTES,
|
||
retention=settings.LOG_RETENTION_DAYS * 2,
|
||
compression="gz",
|
||
encoding="utf-8",
|
||
level="ERROR"
|
||
)
|
||
|
||
# 访问日志
|
||
logger.add(
|
||
LOG_DIR / "access.log",
|
||
format="{time:YYYY-MM-DD HH:mm:ss} | {message}",
|
||
rotation="1 day",
|
||
retention="90 days",
|
||
compression="gz",
|
||
encoding="utf-8",
|
||
filter=lambda record: record["extra"].get("type") == "access"
|
||
)
|
||
|
||
# 操作日志
|
||
logger.add(
|
||
LOG_DIR / "operation.log",
|
||
format="{time:YYYY-MM-DD HH:mm:ss} | {message}",
|
||
rotation=settings.LOG_MAX_BYTES,
|
||
retention=settings.LOG_RETENTION_DAYS,
|
||
compression="gz",
|
||
encoding="utf-8",
|
||
filter=lambda record: record["extra"].get("type") == "operation"
|
||
)
|
||
|
||
return logger
|
||
|
||
|
||
def get_logger(name: str):
|
||
"""获取日志记录器"""
|
||
return logger.bind(name=name)
|
||
|
||
|
||
def log_access(request: Request):
|
||
"""记录访问日志"""
|
||
logger.bind(type="access").info(f"{request.method} {request.url.path} - {request.client.host}")
|
||
|
||
|
||
def log_operation(operator_id: int, operator_name: str, action: str, details: str = ""):
|
||
"""记录操作日志"""
|
||
logger.bind(type="operation").info(f"用户[{operator_id}:{operator_name}] 执行 {action} - {details}")
|
||
|
||
|
||
# 导出logger
|
||
__all__ = ["setup_logger", "get_logger", "log_access", "log_operation", "logger"] |