# 日志配置最佳实践 ## 问题背景 在项目中出现了重复日志的问题,主要原因是: 1. **多重日志处理器配置**:多个模块都手动配置了 `StreamHandler` 2. **日志传播机制**:子 logger 的日志会传播到父 logger,如果都有处理器就会重复输出 3. **缺乏统一配置**:各个模块独立配置日志,没有统一的配置模式 ## 解决方案 ### 1. 统一日志配置工具 创建了 `app/utils/logger_config.py` 提供统一的日志配置功能: ```python from app.utils.logger_config import get_api_logger # 在API模块中使用 logger = get_api_logger(__name__) logger.info("这是API日志") ``` ### 2. 避免重复配置的关键点 ```python # ✅ 正确的配置方式 logger = logging.getLogger(__name__) if not logger.handlers: # 检查是否已配置 logger.setLevel(logging.INFO) handler = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) logger.propagate = False # 关闭传播,避免重复输出 # ❌ 错误的配置方式(会导致重复日志) logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) handler = logging.StreamHandler() # 每次都添加新的处理器 logger.addHandler(handler) # 重复添加处理器 ``` ### 3. 不同模块的使用方式 #### API模块 ```python from app.utils.logger_config import get_api_logger logger = get_api_logger(__name__) logger.info("API操作日志") ``` #### Service模块 ```python from app.utils.logger_config import get_service_logger logger = get_service_logger(__name__) logger.info("业务逻辑日志") ``` #### 工具模块 ```python from app.utils.logger_config import get_utils_logger logger = get_utils_logger(__name__) logger.info("工具函数日志") ``` ## 修复的文件 已修复以下文件中的重复日志配置: 1. `app/api/water.py` - 添加了处理器检查和传播控制 2. `app/api/cd_flux.py` - 添加了处理器检查和传播控制 3. `app/services/cd_flux_service.py` - 添加了处理器检查和传播控制 4. `app/utils/mapping_utils.py` - 已经有正确的配置 ## 测试方法 运行演示脚本来验证修复效果: ```bash conda activate GeoSys python scripts/demos/logging_demo.py ``` ## 最佳实践总结 1. **使用统一配置工具**:优先使用 `app/utils/logger_config.py` 中的函数 2. **检查处理器**:配置前检查 `if not logger.handlers:` 3. **控制传播**:设置 `logger.propagate = False` 避免重复输出 4. **避免重复配置**:不要在多个地方配置同一个logger 5. **根日志配置**:只在应用启动时配置一次根日志系统 ## 注意事项 - 在类中使用日志时,建议在 `__init__` 方法中配置,避免每次调用都重新配置 - 对于 FastAPI 应用,uvicorn 已经有自己的日志配置,避免与其冲突 - 测试环境和生产环境可能需要不同的日志级别和输出方式