## 类中
```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 都会正常工作。