nginx站点中access和error使用的都是默认的日志格式,日志文件命名如下:

    www.xxxx.com.access.log

    www.xxxx.com.error.log

脚本每天处理前一天的日志记录,将日志重新放在压缩文件中,并按月份存放,如下:

    201611/www.xxxx.com.access.20161102.log.zip

    201611/www.xxxx.com.error.20161102.log.zip

脚本如下:

#!/bin/bash
# Description: deal nginx access and error log daily

yes_day_A=`date +%d/%b/%Y -d -1day`
yes_day_A1=`date +%d"\/"%b"\/"%Y -d -1day`
yes_day_E=`date +%Y/%m/%d -d -1day`
yes_day_E1=`date +%Y"\/"%m"\/"%d -d -1day`
yes_day=`date +%Y%m%d -d -1day`
mon=`date +%Y%m`

file_list=`find /etc/nginx/ -type f -name "*.conf" -print0 | xargs -0 egrep '^(\s|\t)*access_log|error_log'|awk '{print $3}'|tr ";" " "|tr '\n' ' '`

for file in $file_list
do
        site=`echo $file |awk -F"log$" '{print $1}'`
        count=0
        if [ -f $file ];then
                echo "Log file found:$file"
                path=`dirname $file`
                cd $path && find ./ -name "*[0-9].log.zip" -mtime +30 -delete
                test ! -d $mon && mkdir $mon
                
                if [[ $file =~ .*acc.* ]];then
                        date_fmt="\[$yes_day_A:"
                        date_str="\[$yes_day_A1:"
                        echo -e "\taccess_file:$file"
                        #continue
                elif [[ $file =~ .*err.* ]];then
                        date_fmt="^$yes_day_E"
                        date_str="^$yes_day_E1"
                        echo -e "\terror_file:$file"
                        #continue
                fi
                
                dst_file="${site}${yes_day}.log"
                grep "$date_fmt" $file >$dst_file
                [ $? -ne 0 ] && let count=count+1
                sleep 5
                
                dfile_size=`ls -l $dst_file |awk '{print $5}'`
                if [ $dfile_size -gt 1024 ];then
                        zip -m -r ${dst_file}.zip $dst_file
                        mv ${dst_file}.zip $mon/
                elif [ $dfile_size -le 10 ];then
                        rm -f $dst_file
                else
                        mv $dst_file $mon/
                fi
              
                [ $? -ne 0 ] && let count=count+1
                sleep 5
                
                if [ $count -eq 0 ];then
                        sed -i "/$date_str/d" $file
                        sed -i "/^$/d" $file
                fi
        fi
done

nginx -t
[ $? -eq 0 ] && nginx -s reload


其中遇到一个坑:sed命令删除文件,是将要删除的内容临时放在当前目录下一个以sed开头的文件中,再删除源文件内容,最后删除临时文件。如果中间出现异常(临时文件导致磁盘空间不足),会终止删除操作,源文件不变,临时文件也不自动处理。