crontab 修改日志文件后,nginx 停止记录

crontab 修改日志文件后,nginx 停止记录

我有一个在 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 系统兼容。

相关内容