#!/bin/bash
#### ping a server and traceroute for Zabbix ####
#### Author : Travis Lee ####
#### Create : 2013-09-12 ####
#### Version : v0.2.3 build.20141227 ####

#### Change History ####
# 2013-09-12 Version : v0.1.0 build.20130912 实现所需的全部功能。包括：ping指定服务器、丢包率超过一定数值进行路由跟踪、将结果发送邮件给指定邮箱、返回结果给Zabbix
# 2013-09-13 Version : v0.2.0 build.20130913 大幅度改进架构，实现持续ping功能。同时修改语句，略为提高执行效率，在监控大量IP时能提升效率
# 2013-12-30 Version : v0.2.1 build.20131230 把路由结果按日期保存，修改临时文件的路径；增加大量注释；可以指定出去的IP（如果打过双线补丁则不需要此功能）
# 2014-12-25 Version : v0.2.2 build.20141225 修改架构，改成异步模式，降低数据库压力，大幅提高效率；去掉所有命令的标准错误输出，防止Zabbix出现无效数据类型而把项目变成不可用
# 2014-12-27 Version : v0.2.3 build.20141227 减少ping的输出信息，节省数据库空间
#### Change History End ####

#使用说明：8个参数，第1个参数指定功能，第2个参数指定被ping IP，这两个为必须参数；3-8仅在第1个参数为traceroute时需要
#第1个参数：支持参数列表 traceroute、ping、loss、min、avg、max、mdev
#traceroute是执行ping操作并返回全部数据给Zabbix，get参数需要2-6的参数
#ping是读取ping的完整结果
#loss是读取ping的丢包率
#min是读取ping的最短时间
#avg是读取ping的平均时间
#max是读取ping的最大时间
#mdev是读取ping延时的方差

#第3-8的参数仅在traceroute功能下有效
#第2个参数：指定ping的服务器IP
#第3个参数：指定发包间隔，单位秒，默认1秒，可使用小数
#第4个参数：指定ping的超时时间，单位秒，必须为整数，最小1秒，超过该时间返回的包也视作丢包；如果不加这个参数，Linux默认为10秒
        #切忌设置小数，否则会一直等待下去
#第5个参数：指定ping的发包数量，默认10个，必须为整数
        #注意：ping的总时间约为($ping_packet_count-1)*$ping_interval+$ping_timeout
        #比如发10个包，发包间隔为0.5秒，超时时间为1秒，则ping的总时间为(10-1)*0.5+min(返回时间,1)
        #如果不丢包，则ping的总时间为4.5秒+ping返回时间，如果丢包，则时间为4.5+1=5.5秒
        #尽量让ping总时长约等于Zabbix的数据更新间隔，这样形成持续ping的效果
#第6个参数：发包大小，默认64字节，必须为整数
#第7个参数：丢包率告警线，默认为10，最大为100，大于等于该数值时触发路由跟踪，设置为0将会每次ping均会做路由跟踪，设置为100则仅在全部丢包时做路由跟踪
#第8个参数：指定出去的IP，如果打过双线补丁则不需要此参数

# Import Environment Variables
source /etc/profile

# change to current dir #
cd $(dirname $0)

# define variables #
function=$1
#目标IP或域名（尽量使用IP，免去DNS解析时间）
target_ip=$2
#功能，可选参数有ping、avg、max、min。ping将进行ping测量，avg、max、min将取得上次ping的结果
ping_result_file=/var/www/traceroute/ping.$target_ip.txt

# get ping result #
case "$function" in
        traceroute)
                #net_ping $@
                nohup /opt/zabbix/etc/scripts/pingscript.sh $@ >/dev/null 2>&1 &
                echo OK
                exit 0
                ;;
        ping)
                cat ping_result_file 2>/dev/null
                ;;
        loss)
                var=$(head -n 1 $ping_result_file 2>/dev/null | grep -o -P "\d+%" | cut -f 1 -d "%")
                if [[ -z "$var" ]] ; then
                        echo 0
                else
                        echo $var
                fi
                ;;
        min)
                awk '/min\/avg\/max/{printf $3}' $ping_result_file 2>/dev/null | awk -F "/" '{print $1}'
                ;;
        avg)
                awk '/min\/avg\/max/{printf $3}' $ping_result_file 2>/dev/null | awk -F "/" '{print $2}'
                ;;
        max)
                awk '/min\/avg\/max/{printf $3}' $ping_result_file 2>/dev/null | awk -F "/" '{print $3}'
                ;;
        mdev)
                awk '/min\/avg\/max/{printf $3}' $ping_result_file 2>/dev/null | awk -F "/" '{print $4}'
                ;;
esac

exit 0
