Nginx访问日志切割脚本,按天分割日志文件

Nginx访问日志默认写入同一个文件,时间一长文件会变得很大,不仅占用磁盘空间,打开和检索也会变慢。
本文介绍如何用系统自带的logrotate工具,配合一个简单的切割脚本,实现Nginx访问日志按天自动分割,适合刚接触服务器运维的读者。

检查环境与准备切割目录

开始之前,先确认Nginx日志的实际路径。
执行以下命令查看Nginx配置中access_log的指向:

grep -r "access_log" /etc/nginx/nginx.conf /etc/nginx/conf.d/ 2>/dev/null

常见的日志路径是/var/log/nginx/access.log。
如果使用了宝塔面板,路径通常是/www/wwwlogs/你的域名.log。

确认路径后,创建用于存放历史日志的目录,例如:

mkdir -p /var/log/nginx/oldlogs

注意:目录权限要和Nginx运行用户一致,通常为www-data或nginx,否则切割后可能无法写入。
可以用ps aux | grep nginx查看运行用户。

编写日志切割脚本

虽然logrotate可以自动切割,但配合一个自定义脚本能更灵活地控制重命名和清理。
新建脚本文件:

vim /usr/local/bin/nginx_log_cut.sh

写入以下内容:

#!/bin/bash
LOG_DIR="/var/log/nginx"
OLD_DIR="/var/log/nginx/oldlogs"
DATE=$(date -d "yesterday" +%Y%m%d)
mv ${LOG_DIR}/access.log ${OLD_DIR}/access_${DATE}.log
# 通知Nginx重新打开日志文件
kill -USR1 $(cat /run/nginx.pid)
# 删除30天前的日志
find ${OLD_DIR} -name "access_*.log" -mtime +30 -delete

保存后赋予执行权限:

chmod +x /usr/local/bin/nginx_log_cut.sh

脚本逻辑是:
把当前access.log重命名为带日期的文件,
然后发送USR1信号让Nginx重新打开新日志文件,
最后删除30天前的旧日志。kill -USR1是Nginx切割日志的标准做法,
不会中断服务。

配置logrotate按天自动执行

系统一般已安装logrotate,直接创建配置文件:

vim /etc/logrotate.d/nginx

写入以下内容:

/var/log/nginx/access.log {
    daily
    missingok
    rotate 30
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        [ -f /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
    endscript
}

关键参数说明:daily表示每天切割一次;rotate 30保留30份历史日志;compress启用gzip压缩节省空间;create指定新日志文件的权限和属主。如果使用自定义脚本,
可以去掉postrotate部分,
改为在crontab中调用脚本。

如果选择用crontab执行脚本,添加定时任务:

crontab -e

加入一行,表示每天凌晨0点1分执行:

1 0 * * * /usr/local/bin/nginx_log_cut.sh

验证切割是否生效

配置完成后,可以手动触发一次logrotate测试:

logrotate -vf /etc/logrotate.d/nginx

-v显示详细过程,-f强制立即切割。
执行后查看日志目录:

ls -lh /var/log/nginx/

应该能看到access.log重新生成,同时出现类似access.log-20250101或access_20250101.log的历史文件。
检查Nginx进程是否正常:

systemctl status nginx

如果服务运行正常,且新日志文件开始写入内容,说明切割成功。

常见报错与避坑指南

报错1:kill: (1234) - No such process
原因:Nginx的pid文件路径不对。用find / -name nginx.pid 2>/dev/null找到实际路径,修改脚本中的/run/nginx.pid。

报错2:切割后日志文件为空
检查Nginx是否真的重新打开了日志。手动执行kill -USR1 $(cat /run/nginx.pid),然后访问网站,看新日志是否有内容。如果没有,可能是SELinux或AppArmor限制了写入,临时关闭测试:setenforce 0。

避坑1:不要直接删除access.log
直接rm会导致Nginx继续向已删除的文件句柄写入,磁盘空间不会释放。必须先重命名,再发信号。

避坑2:logrotate和自定义脚本不要重复执行
如果同时配置了logrotate的postrotate和crontab脚本,可能导致同一天切割两次。建议二选一:要么用logrotate全自动,要么用crontab调用脚本。

避坑3:权限问题
oldlogs目录的属主必须是Nginx运行用户,否则mv操作可能失败。可以用chown www-data:adm /var/log/nginx/oldlogs修正。

几个常见疑问

日志切割后需要重启Nginx吗?
不需要。发送USR1信号是平滑重开日志,不会中断现有连接。只有修改了Nginx主配置文件才需要reload。

可以按小时切割吗?
可以。在logrotate配置中将daily改为hourly,并确保logrotate的cron任务支持每小时执行。或者修改脚本中的date格式为+%Y%m%d%H。

宝塔面板的Nginx日志怎么切割?
宝塔默认已启用日志切割,路径在/www/wwwlogs/下。如果未生效,检查/etc/logrotate.d/下是否有对应规则,或直接在面板的“计划任务”中添加shell脚本。

历史日志太多怎么办?
调整rotate数值,比如改为rotate 7只保留7天。或者结合find命令定期清理,如find /var/log/nginx/oldlogs -mtime +7 -delete。

按照以上步骤操作后,Nginx访问日志就会每天自动分割、压缩并清理,磁盘空间和排查效率都能得到改善。
建议先在测试环境验证脚本,再部署到生产服务器。

分享到:
上一篇
Nginx错误页面自定义,403 404
下一篇
MySQL数据库主从同步搭建,一键脚本部署
1
系统公告

泽御云中秋国庆双节活动上线:新购8折,拼团3.99元起

尊敬的用户:
泽御云“月满中秋·礼贺国庆”双节活动现已开启,活动时间为2026年9月23日至10月10日。 活动期间可享以下福利:
1. 常规云服务器新购使用优惠码“泽御中秋国庆同乐”,符合条件的订单享8折优惠。
2. 香港精品云服务器5人拼团低至3.99元,部分4核4G套餐3人拼团年付388元,续费同价。
3. 新用户购买年付云服务器,符合活动规则可赠送2个月使用时长。
4. 老用户续费季度赠15天,续费年度赠2个月;活动期间升级配置免收配置迁移手续费。
5. 推荐好友成功下单,符合条件的推荐人可获赠7天服务器使用时长。
6. 活动期间享宕机补偿标准翻倍、简单网站迁移协助及技术工单优先处理权益。
温馨提示:优惠码不适用于拼团套餐、活动轻量产品、年付订单及续费订单;拼团套餐为独立特价活动,不与赠时类福利叠加。赠送时长不可折现、退款或跨账户转移,具体规则以活动页面说明为准。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意