## 类中 ```python # 获取 logger logger = logging.getLogger(__name__) logger.error(f"Login process error: {str(e)}", exc_info=True) ``` ## 配置 在 FastAPI 应用中,日志的输出位置取决于你的日志配置。在你展示的代码中,我看到使用了 Python 的标准日志模块 logging,但没有看到具体的日志配置。 默认情况下: - 如果没有特别配置,日志会输出到标准错误流(stderr) - 在开发环境中,这意味着日志会显示在你运行服务器的终端窗口中 - 在生产环境中,具体位置取决于你的部署方式(比如使用 uvicorn 或 gunicorn 运行时,日志可能会被重定向到特定文件) 建议在应用的入口文件(比如 main.py)中添加日志配置。 让我们逐步排查: 1. 首先,确认权限问题: ```yaml:~/viva/docker-compose.yml services: backend: # ... 其他配置 ... volumes: - ./viva-backend/.env:/app/.env - ./viva-backend/logs:/app/logs # 确保这个目录在宿主机上有写入权限 user: "${UID}:${GID}" # 添加这行,使用宿主机的用户权限 ``` 1. 在宿主机上创建日志目录并设置权限: ```bash # 在宿主机执行 mkdir -p ./viva-backend/logs chmod 777 ./viva-backend/logs ``` 1. 修改日志配置,添加更多调试信息: ```python:viva-backend/app/infrastructure/logging/logging_config.py def setup_logging(log_level=numeric_level): try: # 使用绝对路径 log_dir = '/app/logs' print(f"Creating log directory at: {log_dir}") # 调试信息 if not os.path.exists(log_dir): os.makedirs(log_dir) print(f"Created log directory: {log_dir}") # 调试信息 log_file = os.path.join(log_dir, 'app.log') print(f"Log file path: {log_file}") # 调试信息 # 检查文件权限 file_handler = RotatingFileHandler( log_file, maxBytes=10485760, backupCount=5 ) print("Successfully created file handler") # 调试信息 # ... 其余代码保持不变 ... except Exception as e: print(f"Error in setup_logging: {str(e)}") # 调试信息 raise ``` 1. 检查容器日志: ```bash # 查看容器日志 docker-compose logs backend # 进入容器检查 docker-compose exec backend /bin/bash ls -la /app/logs ``` 1. 确保日志配置在应用启动时被正确加载: ```python:viva-backend/app/main.py # 在应用启动时添加调试日志 if __name__ == "__main__": print("Starting application...") # 调试信息 logger = setup_logging() logger.info("Application started") print("Logging configured") # 调试信息 ``` 这些步骤应该能帮助你找出问题所在。通常,如果前端收到 500 错误但日志文件不存在,最可能的原因是: 1. 容器内的权限问题导致无法创建或写入日志文件 2. 日志目录映射配置不正确 3. 日志配置在运行时出错但异常被吞掉了 你可以按照上述步骤逐一排查。如果还是有问题,可以查看 Docker 容器的标准输出日志,因为即使文件日志失败,控制台日志应该还是可以看到的。 --- 日志配置文件(通常名为 logging.conf 或类似的名称) setup_logging() 函数确定具体的输出日志位置 - 控制台(标准输出) - 特定的日志文件 - 系统日志(在 Unix-like 系统上) - 其他日志服务(如 ELK stack, Splunk 等) ## 每个模块最好创建自己的 logger 实例 不能直接使用 main.py 里的 logger。每个模块最好创建自己的 logger 实例,这是 Python logging 的最佳实践。 在 Python 的日志系统中,`logging.getLogger(__name__)` 会根据模块的名称创建一个独立的 logger。这样做有几个好处: 1. **模块隔离**:每个模块有自己的 logger,日志会显示来源模块的名称 2. **灵活控制**:可以针对不同模块设置不同的日志级别 3. **继承配置**:所有模块的 logger 会自动继承根 logger 的配置(handlers、formatters 等) 所以 auth_controller.py 中的写法是正确的: ```python:viva-backend/app/interfaces/api/auth_controller.py logger = logging.getLogger(__name__) ``` 当这个 logger 记录日志时,会显示类似这样的输出: ```Java 2024-03-21 10:30:45,123 - interfaces.api.auth_controller - INFO - Some message ``` 而如果使用 main.py 中的 logger,日志来源会显示为 `__main__` 或 `main`,这样就无法准确追踪日志的来源模块了。 所以建议保持现有的方式,让每个模块使用自己的 logger 实例。只要 main.py 中的 `setup_logging()` 在最开始被调用,所有模块的 logger 都会正常工作。