load_dotenv
find_dotenv
loguru
config.py必须在项目启动时最先被导入,否则其他模块先from loguru import logger使用时,默认 handler 还没被移除,就会出现重复打印。
from dotenv import load_dotenv, find_dotenv import os from loguru import logger import sys """ override 是否覆盖已有系统环境变量 默认 False:系统已存在同名环境变量,.env 中的值不会覆盖 True:强制用 .env 内的值覆盖系统现有环境变量 verbose 日志警告开关 True:如果找不到 .env 文件,控制台输出警告日志 False:文件不存在时静默无提示 """ load_dotenv(find_dotenv(), override=True, verbose=True) """日志文件""" _log_dir = os.path.join(os.path.dirname(__file__), "logs") os.makedirs(_log_dir, exist_ok=True) """# 【关键】先移除默认handler,然后重新添加一个排除progress_tracking的handler""" """# 移除所有默认handler""" logger.remove() """(1)日志输出到控制台""" logger.add( sys.stderr, format="<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>", level="INFO", colorize=True ) """(2)日志输出到日志文件""" logger.add( os.path.join(_log_dir, "logs_{time:YYYY-MM-DD}.log"), level="INFO", # 只记录 INFO 及以上级别(INFO / WARNING / ERROR),DEBUG 不记录 format="<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>", rotation="00:00", # 日志轮转:每天零点自动切新文件,旧文件重命名归档 retention="7 days", # 保留策略:只保留最近 7 天的日志,超期自动删除 compression="zip", # 轮转后的旧日志自动压缩为 .zip,节省磁盘 enqueue=True, # 异步写入:日志先入队列,后台线程批量写文件,避免阻塞主业务 backtrace=True, # 异常时打印完整调用链(loguru 特性,比 Python 默认的 traceback 更详细) diagnose=True, # 异常时显示局部变量值,方便排查问题 ) """(3)错误日志输出到日志文件""" logger.add( os.path.join(_log_dir, "error_{time:YYYY-MM-DD}.log"), level="ERROR", # 只记录 INFO 及以上级别(INFO / WARNING / ERROR),DEBUG 不记录 format="<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>", rotation="00:00", # 日志轮转:每天零点自动切新文件,旧文件重命名归档 retention="7 days", # 保留策略:只保留最近 7 天的日志,超期自动删除 compression="zip", # 轮转后的旧日志自动压缩为 .zip,节省磁盘 enqueue=True, # 异步写入:日志先入队列,后台线程批量写文件,避免阻塞主业务 backtrace=True, # 异常时打印完整调用链(loguru 特性,比 Python 默认的 traceback 更详细) diagnose=True, # 异常时显示局部变量值,方便排查问题 ) API_TEST_KEY = os.getenv("API_TEST_KEY") logger.debug("param:{}", API_TEST_KEY) logger.info("param:{}", API_TEST_KEY) logger.warning("param:{}", API_TEST_KEY) logger.error("param:{}", API_TEST_KEY)如何保证config.py被优先导入
# main.py — 第一行就导入 config import config # ✅ 最先执行,完成 logger 初始化 from fastapi import FastAPI from loguru import logger # 此时 logger 已经配好 app = FastAPI() @app.get("/") async def root(): logger.info("请求来了") # 直接使用配置好的 logger return {"ok": True}.env文件 API_TEST_KEY=skxwq0123jr123021903