shell项目-告警系统
需求背景
使用shell定制各种个性化告警工具,但需要统一化管理、规范化管理。当zabbix服务器之间因为网络原因而无法上报数据时,就可以先通过shell脚本来暂时监控。这样的告警系统属于分布式的,需要在每一台机器上去放置该shell脚本,每一台机器都独立监控,不需要依赖其他机器。
思路:指定一个脚本包,其中包含以下内容
(1)主程序:作为整个脚本的入口,是整个系统的命脉
(2)配置文件:是一个控制中心,用他来开关各个子进程,指定各个相关联的日志文件
(3)子程序:这个才是真正的监控脚本,用来监控各个指标
(4)邮件引擎:是由一个pythen程序来实现,它可以定义发邮件的服务器、发邮件人以及发件人密码。
(5)输出日志:整个监控系统要有日志输出要求:机器角色很多种,但是所有机器上都要部署同样的监控系统,也就是说所有的机器不管什么角色,整个程序框架是一致的,不同之处在于根据不同的角色,定制不同的配置文件。
程序框架
告警系统主脚本
先定义各个监控系统的目录,然后再去定义主脚本,因为是分布式的,所以每一台机器都需要这样去做。可以在其他机器上创建那些目录,然后将这台机器上的脚本拷贝过去,并做一些更改。
将脚本全部放在/usr/local/sbin目录下,方便以后的查找。
创建mon目录,并创建bin 、 conf 、shares 、log 、mail这几个子目录。
-主脚本放在/bin目录下,并写入以下内容
#!/bin/bash
##written by zcy
#是否发送邮件的开关,0为是指不发送
export send=1 //所有的子脚本只是关闭告警,监控还是继续监控
#过滤ip地址
export addr=` /sbin/ifconfig |grep -A1 "ens33: "|awk '/inet/ {print $2}'`
dir=`pwd`
#只需要最后一些目录名
last_dir=`echo $dir |awk -F '/' '{print $NF}'`
#下面判断的目的是,保证执行脚本的时候,我们在bin目录里面,不然监控脚本、邮件和日志很有可能找不到
if [ $last_dir == "bin" ] || [ $last_dir == "/bin/" ] ;
then
conf file="../conf/mon.conf"
else
echo "you shoud cd bin dir"
exit
fi
exec 1 >> ../log/mon.log 2>> ../log.err.log
echo "`date+"%F %T"` load average"
#主脚本中调用了子脚本
/bin/bash ../shares/load.sh
#先检查配置文件中舒服需要监控502
if grep -q 'to_mon_502=1' $conf_files ;
then
export log=`grep 'logfile='$conf file |awk -F '=' '{print $2}' |sed 's/ //g'`
/bin/bash ../shares/502.sh
fi
告警系统配置文件
它主要定义一些开关和日志的路径
切换到conf子目录中创建配置文件mon.conf,并写入以下内容
## to config the options if to monitor
## 定义mysql的服务器地址、端口以及user 、password
to_mon_cdb=0 ##0 or 1, default 0,0 not monitor, 1 monitor
db_ip=192.168.244.136
db_port=3315
db_user=zcy
db_pass=xxxxx
## httpd 如果是1则监控,为0不监控
to_mon_httpd=0
## php 监控为1 不监控为0
to_mon_php_socket=0
## http_code_502 需要定义访问日志的路径
to_mon_502=1
logfile=/data/log/xxx.xxx.com/access.log
## request_count 定义日志路径以及域名
to_mon_request_count=0 //是否监控请求数,为0不监控
req_log=/data/log/www.discuz.net/access.log
domainname=www.discuz.net
配置文件怎么定义取决于子脚本里面需要用到的资源, 可以把用到的所有资源,比如日志、域名等全部写入到子脚本中,前提是机器不多才可以。
将请求日志摘取到配置文件中,目的是为保证通用性。
告警系统监控项目 ##
- 监控项目放在shares目录下,创建load.sh,写入以下内容
#!/bin/bash
load=`uptime |awk -F 'average:' '{print $2}'|cut -d ',' -f1 |sed 's/ //g' |cut -d . -f1` //系统负载的值
if [ $load -gt 10 ] && [ $send -eq "1" ]
then
echo "$addr `date+%T` load is $load" > ../log/load.tmp 这个日志是用来发邮件用到的日志。
/bin/bash ../mail/mail.sh $addr\_load $load ../log/load.tmp
fi
echo "`date+%T` load is $load"
- 创建502.sn
#!/bin/bash
d=`date -d "-1 min" +%H:$M`
c_502=`grep :$d: $log |grep '502' |wc -l `
if [ $c_502 -gt 10 ] && [ $send == 1 ]; then
echo "$addr $d 502 count is $c_502">../log/502.tmp
/bin/bash../mail/mail.sh $addr\_502 ../log/502.tmp
fi
echo "`date+%T` 502 $c_502"
- 监控磁盘 使用率disk.sh
#!/bin/bash
rm -f ../log/disk.tmp
for in `df -h |awk -F '[%]+' '{print $5}' |grep -v Use`
do
if [ $r -gt 90 ] && [ $send -eq "1" ]
then
echo "$addr `date+%T` disk uesrage is $r" >>../log/disk.tmp
fi
if [ -f ../log/disk.tmp ]
then
df -h >> ../log/disk.tmp
/bin/bash ../mail/mail.sh $addr \_disk $r ../log/disk.tmp
echo "`date+%T` disk uesrage in nook"
else
echo "`date+%T` disk uesrage is ok"
fi
awk -F ’ [ % ]+’ /表示以一个或多个空格或%作为分隔符