nginx日志格式:

36.102.228.97 – – [01/Dec/2019:00:03:30 +0800] “GET / HTTP/1.1” 200 1311 “http://XXX.XXXX.cn/” “Mozilla/5.0 (Linux; U; Android 8.0zh-cn; ONEPLUS A6000 Build/PKQ1.180716.001) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/57.0.2987.132 MQQBrowser/8.1 Mobile Safari/537.36” “-”

根据我业务的实际场景,我这个脚本的思路是从nginx原始日志中,提取出访问网页的记录,而访问静态资源比如图片、icon、css等访问记录直接忽略不计。然后根据需要在启动脚本的时候加上参数来选择是否过滤掉爬虫的访问记录,指定某个时间段内的日志,等等。

#!/bin/bash
#程序需要的变量,开始时间、结束时间、保存的文件名
#start_time "29/Nov/2019:23:5"
#end_time "30/Nov/2019:20:3"
#开始时间和结束时间默认是前一天的实际
start_time=`date -d "yesterday" +%d/%b/%Y`
end_time=`date -d "yesterday" +%d/%b/%Y`":23:59:59"
log_data="/data/test/data/alldatas.txt"
allips="/data/test/data/allips.txt"
greaterThan10ips="/data/test/data/greaterThan10ips.txt"
allips_24="/data/test/data/allips_24.txt"
greaterThan10ips_24="/data/test/data/greaterThan10ips_24.txt"
remove_spider=false
send_mail=false
while getopts "s:e:pmt" arg #选项后面的冒号表示该选项需要参数
    do
    case $arg in
         s)
            #运行脚本时 -s 后面加时间
            start_time="$OPTARG"
            ;;
         e)
            #运行脚本时 -e 后面加时间
            end_time="$OPTARG"
            ;;
         p)
            echo "移除spider的访问记录"#运行脚本时 -p 即可,后面不加参数
            remove_spider=true
            ;;
         m)
            echo "程序将会发送邮件"
            send_mail=true
            ;;
         t)
            echo "查询今天的日志"
            start_time=`date +%d/%b/%Y`
            end_time=`date  +%d/%b/%Y`":23:59:59"
            ;;
         ?) #当有不认识的选项的时候arg为?
            echo "start_time & end_time need input,example:29\/Nov\/2019:23:50:00 (日\/月\/年:时:分:秒)"
            exit 1
            ;;
    esac
done
printf "%-20s\t %-20s \n" 开始时间 结束时间
printf "%-20s\t %-20s \n" $start_time $end_time

#我这个网站nginx日志保存地址:/usr/local/nginx/logs/lawyer/access.log 
#提取nginx日志中某个时间段内的记录【grep 筛选出访问主页的记录,去除其他静态资源,awk做时间匹配】
#cat   /usr/local/nginx/logs/lawyer/access.log |egrep -v "txt|js|png|css|jpg|ico" | awk '$4 >="[29/Nov/2019:23:3" && $4 <="[30/Nov/2019:23:30"' > ${log_data}
#cat   /usr/local/nginx/logs/lawyer/access.log |egrep -v "txt|js|png|css|jpg|ico" | awk '$4 >="['${start_time}'" && $4 <="['${end_time}'"' >> $log_data
if [ "$remove_spider" = true ];then
    cat  /usr/local/nginx/logs/lawyer/access.log |egrep -v "txt|js|png|css|jpg|ico" | awk '$4 >="['${start_time}'" && $4 <="['${end_time}'"' |grep -i -v "spider" > $log_data
else
    cat   /usr/local/nginx/logs/lawyer/access.log |egrep -v "txt|js|png|css|jpg|ico" | awk '$4 >="['${start_time}'" && $4 <="['${end_time}'"' > $log_data
fi

#获取所有ip访问次数
cat ${log_data}|awk '{print $1}' |sort | uniq -c | awk  '{print $1"\t"$2}'|sort -k 1 -n -r > $allips

#获取访问次数大于10的ip
cat ${log_data}|awk '{print $1}' |sort | uniq -c | awk '{if ($1 >= 10) print $1"\t"$2}' |sort -k 1 -n -r > $greaterThan10ips

#获取所有ip访问次数_用ip前24位计算
cat ${log_data}|awk '{print $1}' | awk -F "." '{print $1"."$2"."$3".0/24"}' |sort | uniq -c | awk  '{print $1"\t"$2}'|sort -k 1 -n -r > $allips_24

#获取访问次数大于10的ip_用ip前24位计算
cat ${log_data}|awk '{print $1}' | awk -F "." '{print $1"."$2"."$3".0/24"}' |sort | uniq -c | awk  '{print $1"\t"$2}'| awk '{if ($1 >= 10) print $1"\t"$2}' |sort -k 1 -n -r > $greaterThan10ips_24


log_data_count=`wc -l $log_data | awk '{print $1}'`
allips_count=`wc -l $allips | awk '{print $1}'`
allips_24_count=`wc -l $allips_24 | awk '{print $1'}`
greaterThan10ips_count=`wc -l $greaterThan10ips | awk '{print $1}'`
greaterThan10ips_24_count=`wc -l $greaterThan10ips_24 | awk '{print $1}'`
printf "%-12s\t %-8s\t %-8s\t %-12s\t %-8s\n" 总数量 ip ip0/24 大于10次  0/24大于10次
printf "%-12s\t %-8s\t %-8s\t %-12s\t %-8s\n" $log_data_count $allips_count $allips_24_count $greaterThan10ips_count $greaterThan10ips_24_count


info="开始时间:${start_time}  结束时间:${end_time}"
mail_title=
msg="/data/test/data/msg"
cat /dev/null > $msg
if [ "$remove_spider" = true ];then
    sed -i "1i\ ${info} (已移除爬虫)" $log_data
    mail_title=${start_time}"_"${end_time}
    echo "已移除爬虫" > $msg
else
    sed -i "1i\ ${info} 【未移除爬虫】" $log_data
    mail_title=${start_time}"_"${end_time}
    echo "没有移除爬虫" > $msg
fi
sed -i "1i\ $info" $allips
sed -i "1i\ $info" $greaterThan10ips
sed -i "1i\ $info" $allips_24
sed -i "1i\ $info" $greaterThan10ips_24

#如果没有发邮件的需求 删了这些内容即可
if [ "$send_mail" = true ];then
    printf "%-12s\t %-8s\t %-8s\t %-12s\t %-8s\n" 总数量 ip ip0/24 大于10次  0/24大于10次 >>$msg
    printf "%-12s\t %-8s\t %-8s\t %-12s\t %-8s\n" $log_data_count $allips_count $allips_24_count $greaterThan10ips_count $greaterThan10ips_24_count >>$msg

    cat $msg | mailx -s $mail_title -a $log_data -a $allips -a $allips_24 -a $greaterThan10ips -a $greaterThan10ips_24 1111@qq.com,1234@qq.com,123@qq.com
    #cat $msg | mailx -s $mail_title -a $log_data -a $allips -a $allips_24 -a $greaterThan10ips -a $greaterThan10ips_24 1122@qq.com
fi

我主做java开发,shell脚本也是写得少,这个花费了我一整天的时间,不停的测试修改,欢迎和我一起讨论其他优化方案。

 

发表评论