靳闯博客 记录是一种习惯 、分享是一种态度
  • 波浪
  • 波浪
  • 波浪
  • 波浪
nginx日志统计分析脚本
发表于: | 分类: 技术积累 | 标签: Nginx
一个nginx访问日志统计分析的的脚本

脚本功能(2020.12.03优化代码)

# 一、分析当天日志
# 二、分析昨天日志
# 三、分析历史日志

# 具体小功能:
     1: 查询 [ 所有请求ip排行 ]

     2: 查询 [ 请求前40名的ip排行 ]

     3: 查询 [ 请求ip排行最多的ip所请求记录 ]

     4: 查询 [ 指定时间段ip请求排序 ]

     5: 查询 [ 指定时间段指定关键词的请求记录 ]

     6: 查询 [ 所有请求状态码]

     7: 查询 [ 包含指定请求状态码的记录 ]

     8: 查询 [ 指定ip的请求记录 ]

     9: 查询 [ 指定关键词包含的请求记录 ]


使用:修改下日志目录变量;只统计有关access的日志!

使用示例:
# (如果有用cdn,更据cdn提供的选项,再选择修改日志参数以获取请求来源的真实客户端ip)

# 日志记录格式
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                   '$status $body_bytes_sent "$http_referer" '
                   '"$http_user_agent" "$http_x_forwarded_for"';

# 比如当天日志目录为/data/nginx/logs ,修改变量:
daylogs="/data/nginx/logs"

# 比如历史日志目录为/logs ,修改变量:
logs="/logs"

# 历史日志 目录结构为:
/logs/
├── 20181021
│   ├── 20181021-access.log
│   ├── 20181021-blog.access.log
│   ├── 20181021-blog.error.log
│   ├── 20181021-error.log
│   ├── 20181021-me.access.log
│   ├── 20181021-me.access-sofw.log
│   ├── 20181021-me.error.log
│   ├── 20181021-www.access.log
│   └── 20181021-www.error.log
├── 20181022
│   ├── 20181022-access.log
│   ├── 20181022-blog.access.log
│   ├── 20181022-blog.error.log
│   ├── 20181022-error.log
│   ├── 20181022-me.access.log
│   ├── 20181022-me.access-sofw.log
│   ├── 20181022-me.error.log
│   ├── 20181022-www.access.log
│   └── 20181022-www.error.log
├── 20181023
  ·········

统计分析shell脚本

#!/bin/bash
# auuthor: jinchuang

######## 获取昨天日期 ########
qian=`date -d "-1day" +%Y%m%d`

######## 历史日志目录 ########
logs="/logs/2020"

######## 当天日志目录 ########
daylogs="/usr/local/nginx/logs"

######## 处理临时目录 ########
tmpdir="/tmp/nglog"
[ -d $tmpdir ] || mkdir -p $tmpdir

######## 提示文字 ########
logfile="日志文件"
logdir="日志目录"
logfilelist="日志文件列表"
imple="执行"
input=`echo -e "\033[34m请输入要${imple}编号: \033[0m"`
inputcx=`echo -e "\033[34mq:退出 | 请输入查询编号: \033[0m"`
inputdir=`echo -e "\033[34mb:返回 | 请输入${logdir}名称: \033[0m"`
inputlogfile=`echo -e "\033[34mq:退出 b:返回 | 请输入${logfile}编号: \033[0m"`
tips="❤❤❤❤❤❤❤❤❤❤❤❤❤❤"

######## 去重排序 ########
function sq(){
    sort -n |uniq -c |sort -n
}

######## 日志分析 ########
function search() {
    Path=$1
    while true
    do
        echo -e "
     $tips   查询选项   $tips

     1: 查询 [ 所有请求ip排行 ]

     2: 查询 [ 请求前40名的ip排行 ]

     3: 查询 [ 请求ip排行最多的ip所请求记录 ]

     4: 查询 [ 指定时间段ip请求排序 ]

     5: 查询 [ 指定时间段指定关键词的请求记录 ]

     6: 查询 [ 所有请求状态码]

     7: 查询 [ 包含指定请求状态码的记录 ]

     8: 查询 [ 指定ip的请求记录 ]

     9: 查询 [ 指定关键词包含的请求记录 ]

     \033[34mn:[选择其他日志文件] | q:[退出]\033[0m
    "
        logname=`echo -e "\033[33m($file)\033[0m"`
        read -p "$logname$input" a    
        case $a in
            1)
                echo "      $tips 所有请求IP次数统计排序 $tips"
                awk '{print $1}' $Path/$file|sort -n  |uniq -c|sort -n >$tmpdir/allip && pr -w150 -t -6 $tmpdir/allip|more
                
                ## 统计爬虫的请求记录
                bot=`egrep "Googlebot|rssbot|MJ12bot|bingbot|YandexBot|SemrushBot|CCBot|Applebot|Baiduspider|Baiduspider-render|Mediapartners-Google" $Path/$file|awk '{print $1}' |sq|wc -l` && bot=`echo $bot - 1|bc`
                ## 统计所有的请求记录
                ipt=`awk '{print $1}' $Path/$file|sq|wc -l` && ipwc=`echo "$ipt - 1"|bc`
                echo -e "      \033[36m请求ip数量:当前共有 $ipwc 个 | 获取到ip的爬虫 $bot 个 | - 表示未获取到ip的请求数量(未做去重): [直接访问] 和 [谷歌|百度]爬取 和 [未知请求源]\033[0m"
                echo ""

                ## 请求日志记录以 - 开头的请求统计分析
                echo -e "\033[36m      以 - 开头的请求 [直接访问] 和 [谷歌|百度]爬取 和 [未知请求] | 统计分析:\033[0m"
                
                ## 谷歌抓取 
                gbot=`grep ^- $Path/$file|egrep "Googlebot|Mediapartners-Google"|awk '{print $NF}'|sq|wc -l`
                echo -e "\033[31m      # 谷歌爬虫 | ip数量:\033[0m| \033[36m$gbot\033[0m"
                grep ^- $Path/$file|egrep "Googlebot|Mediapartners-Google"|awk '{print $NF}'|sq >$tmpdir/gbot && pr -w150 -t -6 $tmpdir/gbot

                ## 百度抓取
                bbot=`grep ^- $Path/$file|egrep "Baiduspider|Baiduspider-render"|awk '{print $NF}'|sq |wc -l`    
                echo -e "\033[31m      # 百度爬虫 | ip数量:\033[0m \033[36m$bbot\033[0m"
                grep ^- $Path/$file|egrep "Baiduspider|Baiduspider-render"|awk '{print $NF}'|sq >$tmpdir/bbot && pr -w150 -t -6 $tmpdir/bbot

                ## 其他请求源            
                unk=`grep ^- $Path/$file|egrep -v "Googlebot|Mediapartners-Google|Baiduspider-render|Baiduspider"|awk '{print $NF}'|sq|wc -l`
                echo -e "\033[31m      # 直接访问(不经过cdn)或者未知请求来源 | ip数量:\033[0m \033[36m$unk\033[0m"
                grep ^- $Path/$file|egrep -v "Googlebot|Mediapartners-Google|Baiduspider-render|Baiduspider"|awk '{print $NF}'|sq >$tmpdir/unk && pr -w150 -t -6 $tmpdir/unk

            ;;
            2)
                ## 请求ip排名前40的
                echo "$tips 请求次数 IP前40名 $tips"
                awk '{print $1}' $Path/$file|sq|tail -n 40 >$tmpdir/40ip && pr -w150 -t -6 $tmpdir/40ip|more
            ;;
            3)
                ## 请求ip记录最多的访问记录(过滤ip地址包含-的)
                ip=`awk '{print $1}' $Path/$file|sq|tail|grep -v -|tail -n 1|awk '{print $2}'`
                host=`echo -e "\033[36m请求ip: \033[0m"` && date=`echo -e "\033[36m请求时间: \033[0m"`
                request=`echo -e "\033[36m请求地址: \033[0m"` && stats=`echo -e "\033[36m状态码: \033[0m"`
                echo "$tips 请求最多次的IP 所请求的页面统计 $tips"
                awk -v wc="$ip" -v qiuip="$host" -v shijian="$date" -v dizhi="$request" -v zhuang="$stats" '{if($1 == wc) print qiuip$1 "\t"   shijian$4 "\t"    dizhi$7 "\t"zhuang$9}' $Path/$file |more
            ;;
            4)
                ## 统计时间段内的请求记录
                read -p "请输入开始时间【如08:00输入0800】: " a
                read -p "请输入结束时间【如12:00输入1200】: " b
                ## 过滤爬虫记录
                # egrep -v "Googlebot|rssbot|MJ12bot|bingbot|YandexBot|SemrushBot|CCBot|Applebot|Baiduspider|Baiduspider-render|Mediapartners-Google" $Path/$file|awk -F "[-|:| ]+" -v k="$a" -v s="$b" '{if(s >= $3$4 && $3$4 >= k) print $0}' >$tmpdir/$a$b.log
                awk -F "[-|:| ]+" -v k="$a" -v s="$b" '{if(s >= $3$4 && $3$4 >= k) print $0}' $Path/$file>$tmpdir/$a$b.log
                echo "$tips $a-$b 时间段请求IP统计情况 $tips"
                awk '{print $1}' $tmpdir/$a$b.log|sq|more
            ;;
            5)
                ## 统计时间段内关键词的请求记录
                read -p "请输入开始时间【如08:00输入0800】: " a
                read -p "请输入结束时间【如12:00输入1200】: " b
                read -p "请输入查询关键词: " c
                ## 过滤爬虫请求记录
                # egrep -v "Googlebot|rssbot|MJ12bot|bingbot|YandexBot|SemrushBot|CCBot|Applebot|Baiduspider|Baiduspider-render|Mediapartners-Google" $Path/$file|awk -F "[-|:| ]+" -v k="$a" -v s="$b" '{if(s >= $3$4 && $3$4 >= k) print $0}' >$tmpdir/$a$b.log
                awk -F "[-|:| ]+" -v k="$a" -v s="$b" '{if(s >= $3$4 && $3$4 >= k) print $0}' $Path/$file>$tmpdir/$a$b.log
                echo "$tips $a-$b 时间段 ,包含 $c 的请求记录 $tips"
                grep --color "$c" $tmpdir/$a$b.log|more
            ;;
            6)
                ## 请求记录状态码统计
                #赋值(颜色)
                zt=`echo -e "\033[36m状态码:\033[0m"`
                number=`echo -e "\033[36m数量:\033[0m"`
                s200=`echo -e "\033[32m200\033[0m"`
                s301=`echo -e "\033[33m301\033[0m"`
                s302=`echo -e "\033[33m302\033[0m"`
                s304=`echo -e "\033[33m304\033[0m"`
                s403=`echo -e "\033[31m403\033[0m"`
                s404=`echo -e "\033[31m404\033[0m"`
                s500=`echo -e "\033[31m500\033[0m"`
                s502=`echo -e "\033[31m502\033[0m"`
                
                #变量
                for i in 200 301 302 304 403 404 500 502
                do
                    sts="sn"
                    eval ${sts}_${i}=`awk '{print $9}' $Path/$file|grep $i|wc -l`
                done
                
                #打印格式
                echo "$tips 当天请求 http状态码统计情况 $tips"
                printf "%-20s %-19s %-19s %-18s %-18s %-18s %-18s %-18s %-10s\n" $zt $s200 $s301 $s302 $s304 $s403 $s404 $s500 $s502
                printf "%-19s %-10s %-10s %-9s %-9s %-9s %-9s %-9s %-9s %-10s\n" $number $sn_200 $sn_301 $sn_302 $sn_304 $sn_403 $sn_404 $sn_500 $sn_502
        
            ;;
            7)
                ## 查找指定状态码的请求记录
                read -p "请输入要查询请求记录的状态码:" sta
                echo "$tips 查询指定状态码 所请求的页面统计 $tips"
                ## 过滤爬虫请求记录
                # egrep -v "Googlebot|rssbot|MJ12bot|bingbot|YandexBot|SemrushBot|CCBot|Applebot|Baiduspider|Baiduspider-render|Mediapartners-Google" $Path/$file|awk -v jl=$sta '{if($9 == jl)print $0}' |more
                awk -v jl=$sta '{if($9 == jl) print $0}' $Path/$file|more
            ;;
            8)
                ## 查询指定ip请求的记录
                read -p "请输入ip地址:" ip
                echo "$tips 指定ip 所请求页面统计 $tips"
                awk -v sip="$ip" '{if($1 == sip || $NF == sip) print $0}' $Path/$file|more
            ;;
            9)
                ## 查询包含指定关键词的请求记录
                read -p "请输入要查询记录包含的相关词:" ci
                read -p "1: 精准匹配 | 2: 模糊匹配 :" gp
                case $gp in
                    1)
                        echo -e "$tips 查询包含 \033[31m$ci\033[0m 关键词的记录(如果为空则为没有查询到有关记录) $tips" && grep -w "$ci" $Path/$file |more
                    ;;
                    2)
                        echo -e "$tips 查询包含 \033[31m$ci\033[0m 关键词的记录(如果为空则为没有查询到有关记录) $tips" && grep "$ci" $Path/$file |more
                    ;;
                    *)
                        echo -e "     \033[31m❎  请输入正确的编号\033[0m"
                    ;;
                esac
            ;;
            n)
                break
            ;;
            q)
                exit
            ;;
            *)
                echo ""
                echo -e "     \033[31m❎  请输入正确的${imple}编号\033[0m"
            ;;
        esac
    done
}

######## 查询循环 ########
function xh() {
    ls $1|egrep "log$" >/dev/null
    if [ $? == 0 ];then
        while true
        do
            echo ""
            echo "$tips ${logfilelist} $tips"
            ls $1 |grep -v error |grep log$|tr "\t" "\n"|nl
            ls $1 |grep -v error |grep log$|tr "\t" "\n" >$tmpdir/loglist
        
            logline=`ls $1 |grep -v error |grep log$|tr "\t" "\n"|wc -l`
            read -p "${inputlogfile}" u
    
            case $u in
                [0-9]*)
                    if [[ $u -gt $logline || $u -lt 0 ]]
                    then
                        echo ""
                        echo -e "     \033[31m❎  请输入正确的${logfile}数字编号 \033[0m"
                        echo ""
                    else
                           file=`sed -n "$u"p $tmpdir/loglist` && search "$1"
                    fi
                ;;
                q)
                    exit
                ;;
                b)
                    break
                ;;
                *)
                    echo ""
                    echo -e "     \033[31m❎  请输入${logfile}数字编号 \033[0m"
                    echo ""
            esac
        done
    else
        echo ""
        echo -e "     \033[31m❎  日志目录中没有.log结尾的日志文件 \033[0m" && continue
        echo ""
    fi
}

######## 历史日志 ########
function historylog(){
    while true
    do
        echo "$tips 历史日志目录列表 $tips"
        ls $logs && ls $logs >$tmpdir/histlog
        read -p "${inputdir}" hisdir
        case $hisdir in
        b)
            break
        ;;
        *)
            grep -w "$hisdir" $tmpdir/histlog >/dev/null
            if [ $? == 0 ]
            then
                xh "$logs/$hisdir"
            else
                echo ""
                echo -e "     \033[31m❎  [\033[0m\033[32m$logs/\033[0m\033[33m$hisdir\033[0m\033[31m]目录不存在,请输入正确的${logdir}名称 \033[0m"
                echo ""
            fi
        ;;
        esac
    done
}

######## 执行脚本 ########
while true
do
    echo "
$tips Nginx日志分析查询 $tips
     1: 查询当天 (回车)
     2: 查询昨天
     3: 查询历史"
    read -p "${inputcx}" cx
    case $cx in
        3)
            ## 历史日志 ##
            historylog
        ;;

        2)
            ## 昨天日志 ##
            xh "$logs/$qian"
        ;;
        q)
            exit
        ;;
        
        1|"")
            ## 当天日志 ##
            xh "$daylogs"
        ;;
    
        *)
            echo ""
            echo -e "     \033[31m❎  请输入正确的查询编号\033[0m"
        ;;
    esac
done

查询当天日志示例

ns.png


查询昨天日志示例

ns1.png


查询历史日志示例

ns2.png


执行分析实例

ns3.pngns4.png


商业转载请联系作者获得授权,非商业转载请注明出处 本文地址:https://me.jinchuang.org/archives/156.html

如果这篇文章帮助到了你,我感到十分荣幸!


📬 评论留言 ↴

TOP