Nginx日志会随着日益增多的请求而逐渐变大,有些场景下会有切割日志的需求,这里的切割即剪切。我是打算对Nginx日志进行分析,但如果不把已经分析完的数据及时丢出去,会造成重复性的分析。

分析Nginx日志的代码可以参考:Python分析Nginx日志 - SSgeek - 博客园 (cnblogs.com)



Nginx定时分割日志,需要两个步骤:

  • 写一个脚本,将当前日志移动到指定位置,并根据时间命名该日志,完成后发送信号给Nginx。

  • 定时运行该脚本。



一、编写脚本

脚本文件cut_log.sh如下:

#!/bin/bash
PID=/run/nginx.pid

LOG_PATH="/var/log/nginx" # 原始日志文件保存目录
BACK_PATH="/var/log/nginx/back_log" # 备份日志保存目录
[ -d $BACK_PATH ] || mkdir $BACK_PATH #判断用于备份日志的目录是否存在,没有的话新建目录


#判断access.log是否不为空
if [ -s "${LOG_PATH}/access.log" ]; then

RECORD_TIME=$(date +%Y-%m-%d.%H:%M --date="-1 minute") # 新日志文件以时间命名
mv ${LOG_PATH}/access.log ${BACK_PATH}/access.${RECORD_TIME}.log # 使用 mv 备份,切割日志

kill -USR1 `cat $PID` # 等价于 `nginx -s reopen` #向Nginx主进程发送信号,USR1 信号用于重新打开日志文件

else
echo "access.log为空,暂不执行切割..."
fi

有个问题需要注意,就是如果网站访问量不大,同时又不想设置很长的执行间隔,就要在切割日志前先判断access.log日志文件是否为空,若为空,就放弃移动,否则会创建一大堆的新的空日志文件!毫无意义。因此,在代码中加了一段if-else-fi语句,但这个对于该脚本不是必需的。


另外,新生成的日志是以时间命名的。 在linux命令行中直接输入 date +%Y-%m-%d/%H:%M:%S 即可得到当前的 年月日时分秒 信息。而后面的 --date="-1 minute" 的作用是在当前时间基础上减去1分钟,退回一分钟的表示方法更加科学。


最后,将这段代码保存在linux系统中的某个位置,我这里直接放在了 /var/log/nginx目录里。然后,为该脚本赋权。这个很关键,如果不设置,会报Permission denied的错误。

chmod u+x  /var/log/nginx/cut_log.sh

至此,最好手动测试一下该脚本是否有效,否则定时任务执行失败也没办法找到错误原因(除非单独给crontab设日志)。测试方法很简单,在命令行中直接输入执行bash /var/log/nginx/cut_log.sh,查看access.log文件是否按预期切割了。



二、设置定时任务

在Linux系统下,直接使用crontab即可。cron是一个linux下的定时执行工具,可以在无需人工干预的情况下定时运行作业。

首先安装:

yum install crontabs


然后在任务列表上新增我们的定时任务:

crontab -e


该命令类似于vim,会打开一个文件,在里面新增数据的操作与vim一样。新增下面一行:

*/1 * * * * /var/log/nginx/cut_log.sh  &>/dev/null 2>&1

这条任务其实就只有6个参数:分钟、小时、日、月、星期几、运行命令、任务日志的输出形式。

1、前4个参数

  • 星号(*)代表所有可能的值;斜线(/)表示间隔频率;横杠(-)表示时间范围。

    *    *    *    *    *
    - - - - -
    | | | | |
    | | | | +----- 星期中星期几 (0 - 6) (星期天 为0)
    | | | +---------- 月份 (1 - 12)
    | | +--------------- 一个月中的第几天 (1 - 31)
    | +-------------------- 小时 (0 - 23)
    +------------------------- 分钟 (0 - 59)
  • 举例:

    每10分钟执行一次:	   */10 * * * *
    每小时0分执行一次: 0 * * * *
    每两小时0分执行一次: 0 */2 * * *
    每天0点0分执行一次: 0 0 * * *

    2、第6个参数

这个参数也很重要,如果定时任务执行失败,可以从日志中找失败的原因。(该日志是追加形式来写)

  • &>/dev/null 2>&1:定时任务不输出内容。等同于这一部分留空

  • >> /tmp/full.log 2>&1:将正确和错误日志都输出到 /tmp/full.log

  • 2> /tmp/error.log &:只输出错误日志到 /tmp/error.log

  • \> /tmp/acc.log &:只输出正确日志到 /tmp/acc.log


新增完成后,保存并退出该文件,然后执行下面的两条命令:

crontab -l    # 查看定时任务是否添加成功,会输出目前的任务列表
sudo service crond restart # 重启crond服务

定时任务设置完成!





相关的一些命令:

find /var/log/nginx/back_log -mtime 3 -type f -name \*.log | xargs rm -f  # 定期删除3天前的日志文件(按后缀搜索)

find /var/log/nginx/back_log -mtime 3 -type d -name "log-*" | xargs rm -rf # 定期删除3天前的日志文件夹(按名称的前缀搜索)