用shell脚本分析Nginx访问日志IP地址来源

该日志分析脚本以Ubuntu server 10.04为基础,由于Nginx没有自带切割日志功能,用以下脚本把Nginx生成的日志每天零点做一次切割,目录按年/月分,例如10月份31天的都放在2010/10/下面.
切割脚本:

#!/bin/bash
 PATH_LOGS="/usr/local/nginx/logs"
 YEAR=`date -d "-1 days" +"%Y"`
 MONTH=`date -d "-1 days" +"%m"`
 mkdir -p $PATH_LOGS/$YEAR/$MONTH
 mv $PATH_LOGS/access.log $PATH_LOGS/$YEAR/$MONTH/access_$(date -d "-1 days" +"%Y%m%d").log
 kill -USR1 `cat $PATH_LOGS/nginx.pid`

分析IP地址来源的脚本,以ip168网站为基础的:

#!/bin/bash
#====================================================
#Author:zhangll
#MAIL:lsanotes@gmail.com
#====================================================
help='\nUsage:./ip.sh $1 $2\nOption:\n$1\tYear(Default:Current Year)\n$2\tMonth(Default:Current Month)'
YEAR=$1
MONTH=$2
IPSUMFILE=access_ip.log
SAVEFILE=ipaddress.txt
 
if [ "$1" == "--help" ]
then
 echo -e "$help"
 exit 1
fi
>$IPSUMFILE
echo -e "IP地址\t\t\t\t\t来源\n----------------------------------------------------">$SAVEFILE
if [ "$1" = "" ]
then
 YEAR=`date +"%Y"`
fi
 
if [ "$2" = "" ]
then
 MONTH=`date +"%m"`
fi
#log path
LOG_DIR=/usr/local/nginx/logs/$YEAR/$MONTH
for i in $LOG_DIR/*.log
do
 FILE=`basename $i`
 awk '!a[$1]++{print $1}' $i >> $IPSUMFILE
done
 
#remove local ip address
 
sed -i '/192.168.2./d' $IPSUMFILE
#get ip souce
for i in `cat access_ip.log`
do
 wget http://www.ip168.com/ip/?ip=$i &>/dev/null
 address=`cat index.html\?ip\=$i | grep 参考数据二|sed 's/<div>.*:\(.*\)<.*>/\1/'`
 
 if [ "$address" == "" ];then
   echo -n "Failed get $i source,please check..."
 fi
echo "$i$address" >> $SAVEFILE
rm -rf index.html\?ip\=$i
done
#Convert Dos text files to the Unix format
which fromdos &>/dev/null
if [ $? != 0 ];then
 apt-get -f install tofrodos
fi
 
fromdos ipaddress.txt
 
echo "All work done."

执行后的结果存放在ipaddress.txt文件,我的一个例子结果如下:

IP地址                                  来源
——————————————————————————-
86.109.113.73                           英国 Orange网络公司
125.89.75.100                           广东省珠海市 电信
118.145.31.154                          北京市 电信通IDC机房
67.208.74.165                           美国 弗吉尼亚州
27.189.198.244                          中国
222.130.133.0                           北京市 联通ADSL
221.219.115.221                         北京市海淀区 联通ADSL
125.89.75.100                           广东省珠海市 电信
124.207.140.12                          北京市 电信通
86.109.113.73                           英国 Orange网络公司
27.189.198.244                          中国
117.73.224.120                          北京市 方正宽带
188.165.64.210                          英国
222.130.133.0                           北京市 联通ADSL
221.219.115.221                         北京市海淀区 联通ADSL
173.234.148.162                         北美地区
222.130.133.0                           北京市 联通ADSL
203.196.19.234                          日本


11 Responses to “用shell脚本分析Nginx访问日志IP地址来源”

  1. centos 说道:

    使用您的脚步测试了下,在最终的ipaddress.txt,IP都会被过滤出来,但是来源是空的。请问是什么原因造成的?感谢分享这个脚本
    husyuan2010@163.com

  2. zhangll 说道:

    能把你过滤的几个IP发给我看看吗?看看是不是抓取不到来源

    你的环境是什么?

  3. centos 说道:

    环境是我自己平时做实验的环境,和大多数nginx配置差不多。

    能过滤出IP地址,但是没有来源信息
    IP地址 来源
    —————————————————-
    192.168.1.253
    119.146.78.26
    58.60.1.17
    192.168.1.1
    192.168.1.121
    192.168.1.253
    192.168.1.253
    183.0.96.184
    123.154.65.184
    123.152.152.49
    60.31.110.112
    113.142.9.160
    60.183.227.230
    123.133.187.251
    219.144.139.105

  4. zhangll 说道:

    执行脚本的时候也没有任何提示吗?

    #get ip souce
    for i in `cat access_ip.log`
    do
    wget http://www.ip168.com/ip/?ip=$i &>/dev/null
    address=`cat index.html\?ip\=$i | grep 参考数据二|sed ‘s/.*:\(.*\)/\1/’`

    if [ "$address" == "" ];then
    echo -n “Failed get $i source,please check…”
    fi
    这段是得到来源的,你输出address看看,改成这样
    #get ip souce
    for i in `cat access_ip.log`
    do
    wget http://www.ip168.com/ip/?ip=$i &>/dev/null
    address=`cat index.html\?ip\=$i | grep 参考数据二|sed ‘s/.*:\(.*\)/\1/’`
    echo $address
    if [ "$address" == "" ];then
    echo -n “Failed get $i source,please check…”
    fi

  5. centos 说道:

    脚步改过后,执行依然只能过滤出IP,得不到来源信息。

    “Failed get 125.33.13.80 source,please check…”sed:-e 表达式 #1,字符 1:unknown command: `?

    “Failed get 114.246.133.100 source,please check…”sed:-e 表达式 #1,字符 1:unknown command: `?

    “Failed get 110.178.43.109 source,please check…”./ip.sh: line 54: apt-get: command not found
    ./ip.sh: line 57: fromdos: command not found
    All work done.
    [root@web logs]#

  6. zhangll 说道:

    你是的系统是centos?这个脚本是在ubuntu上写的,
    centos上最后一段就应该改了
    #Convert Dos text files to the Unix format
    which dos2unix &>/dev/null
    if [ $? != 0 ];then
    yum install dos2unix
    fi

    dos2unix ipaddress.txt

    echo “All work done.”

    另外,sed这个正则你最好手动输入一次,怀疑直接复制会有少许的问题

  7. centos 说道:

    按照你的提示,做了修改,但是最终执行结果还是无法得到源地址。我不是很擅长shell特继续请教。
    Failed get 125.33.13.80 source,please check…
    Failed get 114.246.133.100 source,please check…
    Failed get 110.178.43.109 source,please check…dos2unix: converting file ipaddress.txt to UNIX format …
    “All work done.”
    [root@web logs]#

  8. zhangll 说道:

    这样吧,把你执行的这个脚本发到我邮箱,我看看是哪有问题,这个脚本在我机器上是正常运行的

  9. centos 说道:

    好的,注意查收!

  10. zhangll 说道:

    脚本看了,没看出什么问题
    看一下你的语言环境是utf8的吗,你这样执行看一下

    export LANG=en_US.UTF8;./ip.sh

  11. 很棒 说道:

    哥们真的很棒,我感觉你的脚本又增加下省份的统计

Post a Comment