我有一个在 nginx + gunicorn 上运行的 Web 服务器 (django)。nginx 将其常规日志写入:
~/myproject/log/access.log
并将错误写入:
~/myproject/log/error.log
几个月来它一直运行良好。
最近我发现我必须找到一种方法来在这些日志占用所有磁盘空间之前自动删除它们,所以我编写了一个脚本,如果文件超过 x 行则删除文件的部分内容,并且我让 crontab 每 24 小时运行一次该脚本。
然后我注意到每次 crontab 执行我的脚本时,nginx 都会停止记录。我可以通过重新启动 nginx 来恢复它,但是 crontab 完成其工作后它会再次停止记录。
这是我的脚本:
LOG_PATH="/home/ubuntu/myproject/log/"
MAX_LINE_COUNT="400000"
NOW=$(TZ='Asia/Taipei' date +"%Y-%m-%d %H:%M")
echo "$NOW (GMT+8) start truncate_logs.sh"
for f in "$LOG_PATH"*; do
line_count=`wc -l < "$f"`
echo "$f has $line_count lines"
if [ "$line_count" -gt "$MAX_LINE_COUNT" ]
then
lines_to_truncate=$((line_count-MAX_LINE_COUNT))
sed -i '1,'"$lines_to_truncate"'d' "$f"
echo "truncated $lines_to_truncate lines"
else
echo "pass"
fi
done
我想知道 nginx 和 crontab 是否同时访问该文件,并且会破坏 nginx 的日志记录行为?
此外,当 nginx 停止在“access.log”中写入日志时,它仍然会在“error.log”中写入错误。“error.log”文件中的行数总是较少,所以我的脚本从未修改过该文件。这是我怀疑我对“access.log”脚本的修改改变了 nginx 行为的原因之一。
答案1
您应该就此事使用适当的 nginx logrotate 脚本。
以下是一个例子:
"/var/log/nginx/*.log" {
daily
rotate 7
size 100M
dateext
dateformat -%Y%m%d-%s
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
[ ! -f /run/nginx.pid ] || kill -USR1 `cat /run/nginx.pid`
endscript
}
您还可以启用 lorotation 来每小时而不是每天检查文件大小。
sudo ln -s /etc/cron.daily/logrotate /etc/cron.hourly/logrotate
这些示例来自 ubuntu server 14.04,但应该与其他 *Nix 系统兼容。