在Linux服务器上使用nohup后台启动FastAPI应用时,如果不合理管理日志,日志文件会无限增长,最终占满磁盘空间,导致CPU使用率飙升甚至服务器宕机。本文用最简单的方式,详细介绍FastAPI日志基础知识,配合示例代码和实用操作,帮助你轻松避免这类问题,保证服务稳定运行。
1. 为什么nohup启动FastAPI会导致日志无限增长?
nohup默认会把程序的标准输出(stdout)和标准错误(stderr)写入当前目录下的nohup.out文件,如果不主动重定向,nohup.out会不断变大,最终占满磁盘- FastAPI默认的访问日志不会自动写入文件,若没有配置日志系统,日志会堆积在控制台或默认文件中,难以管理
- 日志文件过大,磁盘I/O压力增大,CPU负载升高,严重时服务器可能挂掉
2. 如何合理配置FastAPI日志?
2.1 FastAPI结合uvicorn写日志到文件,并实现日志轮转
FastAPI使用uvicorn作为服务器时,默认访问日志不易捕获到,需要调整uvicorn日志配置,才能把日志写入文件并自动轮转。
示例代码:
from fastapi import FastAPI
import logging
from logging.handlers import TimedRotatingFileHandler
from uvicorn.config import LOGGING_CONFIG
app = FastAPI()
# 让uvicorn访问日志向上传递,方便自定义处理
LOGGING_CONFIG['loggers']['uvicorn.access']['propagate'] = True
# 创建按天轮转的日志处理器,保留7天日志
handler = TimedRotatingFileHandler(
"fastapi_access.log", when="midnight", backupCount=7, encoding='utf-8'
)
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logging.getLogger("uvicorn.access").addHandler(handler)
@app.get("/")
async def root():
logging.getLogger("uvicorn.access").info("访问根路径")
return {"message": "Hello FastAPI with logging"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8080)
- 访问日志会写入
fastapi_access.log,每天自动切割,最多保留7天 - 方便后期查看和管理日志。
3. 使用nohup启动FastAPI时如何避免nohup.out无限增大?
默认执行:
nohup uvicorn main:app --host 0.0.0.0 --port 8080 &
会生成无限大的nohup.out文件。
正确做法:重定向日志输出到指定文件
nohup uvicorn main:app --host 0.0.0.0 --port 8080 > fastapi_nohup.log 2>&1 &
> fastapi_nohup.log:标准输出写入fastapi_nohup.log2>&1:标准错误重定向到标准输出&:后台运行
如果不需要保存日志,可以重定向到/dev/null:
nohup uvicorn main:app --host 0.0.0.0 --port 8080 > /dev/null 2>&1 &
但建议保留日志方便排查问题
4. 使用logrotate定期轮转和压缩日志,防止日志文件过大
4.1 安装logrotate(大部分Linux默认已安装)
# CentOS
sudo yum install logrotate
# Ubuntu/Debian
sudo apt-get install logrotate
4.2 创建logrotate配置文件
假设日志文件路径为/var/log/fastapi_nohup.log和/var/log/fastapi_access.log,新建配置文件/etc/logrotate.d/fastapi:
/var/log/fastapi_nohup.log /var/log/fastapi_access.log {
daily # 每天轮转
rotate 7 # 保留7个备份
size 100M # 文件超过100MB时立即轮转
compress # 轮转后压缩旧日志
delaycompress # 延迟一天后压缩
missingok # 文件不存在不报错
notifempty # 空文件不轮转
copytruncate # 复制后截断日志,适合持续写入的日志文件
}
4.3 手动测试logrotate配置
sudo logrotate -vf /etc/logrotate.d/fastapi
4.4 定时自动执行
logrotate通常由系统的cron自动执行,无需手动配置。
5. 如何监控磁盘和日志文件大小?
定期检查日志文件大小和磁盘使用,避免异常:
# 查看日志文件大小
du -sh /var/log/fastapi_*.log
# 查看磁盘使用情况
df -h
# 查找系统中最大的20个文件
sudo du -ah / 2>/dev/null | sort -rh | head -20
当发现日志文件过大时,可以手动清理或调整logrotate策略