商城首页欢迎来到中国正版软件门户

您的位置:首页 >宝塔面板Nginx日志自动清理方法

宝塔面板Nginx日志自动清理方法

  发布于2026-04-16 阅读(0)

扫一扫,手机访问

直接删 access.log 会导致 Nginx 不写日志,因其仍通过文件描述符向已删除但未关闭的文件写入,且部分版本不会自动重建日志文件;正确做法是用 kill -USR1 信号通知 Nginx 重新打开日志文件。

宝塔面板怎么自动清理长期堆积占据空间的Nginx访问日志_编写定时Shell脚本执行日志按天切割与删除

为什么直接删 access.log 会导致 Nginx 不写日志?

因为 Nginx 启动后会持有一个指向日志文件的文件描述符(fd),即使你用 rm access.log 删除了文件,实际磁盘空间并不会立刻释放——那个 fd 还在往“已删除但未关闭”的文件里写数据。更糟的是,有些版本的 Nginx 在日志文件被删后不会自动重建,导致后续访问完全不记录。

正确做法是用 kill -USR1 发信号让 Nginx 主进程重新打开日志文件,它会按 access_log 指令中配置的路径新建一个 access.log,旧文件则可安全清理。

  • 确认你的 Nginx 配置里 access_log 是绝对路径,比如 /www/wwwlogs/example.com.log,不是 logs/access.log 这种相对路径(否则切割逻辑容易错位)
  • 执行前先测试信号是否生效:nginx -t && kill -USR1 $(cat /www/server/nginx/logs/nginx.pid)
  • 宝塔默认把 Nginx PID 写在 /www/server/nginx/logs/nginx.pid,别去读 ps aux | grep nginx 找进程号,容易误杀 worker 进程

怎么用 Shell 脚本实现「按天切割 + 保留 30 天」?

宝塔自带的“日志切割”功能只支持按月/周,且不支持自定义保留天数;手动写脚本反而更可控。核心逻辑三步:移动旧日志 → 发送 USR1 → 删除超期文件。

以下是一个生产环境验证过的脚本,保存为 /www/server/scripts/cut_nginx_logs.sh

#!/bin/bash
LOG_DIR="/www/wwwlogs"
KEEP_DAYS=30
DATE=$(date -d "yesterday" +%Y-%m-%d)

移动所有 .log 文件(排除 .log.2024-xx-xx 格式,避免重复切割)

find "$LOG_DIR" -maxdepth 1 -name ".log" ! -name ".log.*" | while read log; do [ -f "$log" ] || continue mv "$log" "${log}.${DATE}" done

通知 Nginx 重新打开日志文件

kill -USR1 $(cat /www/server/nginx/logs/nginx.pid 2>/dev/null) 2>/dev/null

删除早于 KEEP_DAYS 的切割日志(只删 .log.YYYY-MM-DD 格式)

find "$LOG_DIR" -maxdepth 1 -name ".log." -type f -mtime +$KEEP_DAYS | xargs rm -f

  • find ... ! -name "*.log.*" 是关键:跳过已切割的文件,防止某天脚本重复运行时把 access.log.2024-05-01 又改成 access.log.2024-05-01.2024-05-01
  • -mtime +30 表示“修改时间超过 30 天”,不是创建时间,所以必须确保切割当天就改名(脚本用 yesterday 是为了匹配真实访问日期)
  • 别用 date +%F 直接取当天——Nginx 日志是滚动写的,当天的日志还在写入中,切早了会丢数据

宝塔定时任务怎么配才不踩坑?

在宝塔面板「计划任务」里添加,类型选「Shell 脚本」,脚本内容填上面的完整代码(或填路径 /www/server/scripts/cut_nginx_logs.sh),但注意三个硬性条件:

  • 执行周期必须设为「每天 00:10」这类凌晨低峰时间,不能设成「每小时」或「每分钟」——kill -USR1 频繁触发可能导致 worker 进程短暂卡顿
  • 脚本文件权限必须是 755,且属主是 root(宝塔计划任务默认以 root 运行,但若你手贱 chown www:www 就会因权限不足失败)
  • 务必勾选「执行前先检测脚本是否存在」,否则脚本路径写错或被误删,宝塔不会报错,只会静默跳过

如果发现日志没按预期切割,去「计划任务」列表点「查看日志」,重点检查有没有 cat: /www/server/nginx/logs/nginx.pid: No such filemv: cannot move 'xxx' to 'xxx.2024-05-01': Device or resource busy ——前者说明 Nginx 没跑,后者说明你脚本逻辑没避开正在写的日志文件。

哪些域名日志该切、哪些不该碰?

宝塔默认把所有站点日志都扔进 /www/wwwlogs/,但并非所有都要切割。比如:

  • default.logerror.log 必须切——它们体积增长快,且错误日志长期不清理会影响排查效率
  • 用 CDN 的站点(如启用了又拍云、Cloudflare),其 access.log 实际只记录回源请求,量很小,可设为保留 7 天甚至关掉访问日志
  • API 接口类站点(如 api.example.com.log)建议单独配置日志路径,比如 /www/wwwlogs/api/,再用独立脚本管理——避免和前端日志混在一起,删错风险高
  • 千万别对 /www/wwwlogs/xxxxx.log 这种带随机字符串的宝塔后台日志做切割,那是面板自身行为,格式不固定,脚本会误操作

最保险的做法:先用 ls -lt /www/wwwlogs/ | head -20 看看哪些文件最大、修改最频繁,再决定脚本里 find-name 模式,而不是无差别匹配所有 *.log

本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注