直接删 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,旧文件则可安全清理。

怎么用 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

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

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

如果发现日志没按预期切割,去「计划任务」列表点「查看日志」,重点检查有没有 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/,但并非所有都要切割。比如:

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

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