一、功能介绍:
【1】统计负载、内存、磁盘、swap使用率,
【2】统计连接数、流量、并根据使用情况发邮件告警
二、通过代码学习
本节是通过编写一段简单资源统计告警代码来加深对shel编程的。可以通过执行、调试这段脚本来加深知识点。
#!/bin/bash
#11.sh v1
PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
export LANG=zh_CN.UTF-8
export PATH
#定义变量
HostName=$(hostname -s)
IP=$(ifconfig | awk '/inet /{sub(/addr:/,"",$2);print $2}')
NOTICE_MAIL="aa@bb.com" #多个邮箱逗号隔开
mail_content="/tmp/.alarm.info"
#初始化配置邮件发送的信息
init(){
which mail >/dev/null
if [ $? -ne 0 ];then
yum -y install mailx
fi
if [ -s /etc/mail.rc ];then
grep "set smtp-auth-user=" /etc/mail.rc >/dev/null
if [ $? -ne 0 ];then
cat >> /etc/mail.rc << EOF
set from=user@163.com
set smtp=smtp.163.com
set smtp-auth-user=user@163.com
set smtp-auth-password=password
set smtp-auth=login
EOF
fi
fi
}
#邮件发送函数
AlarmNotice(){
Mail_Title="[WARN] $HostName[$IP]Server performance alarm"
mail -s "$Mail_Title" "$NOTICE_MAIL" < $mail_content
}
CollectSysinfo(){
#获取当前系统时间
Htime=$(date +"%Y-%m-%dT%H:%M:%S%z")
Timestamp=$(date +%s000)
#读取系统负载
Load=$(uptime | awk 'NR==1{gsub(/,/,"");print $(NF-2)}')
#读取swap使用率
SwapUsed=$(free | awk '/Swap/&&0!~$2{printf("%.3f\n",($3/$2))}')
#读取内存使用率
MemUsed=$(free -m|awk '/Mem/{printf("%.3f\n",($2-$7)/$2)}')
#读取磁盘使用率
DiskUsed=$(df -P | sed "1d"|awk 'gsub(/%/,""){print $(NF-1)/100}'|sort -r|head -1)
TcpConn=$(ss -s|awk '/TCP:/{print $2}')
#获取网卡流量
sar -n DEV 1 5 >/tmp/.sarDEV.txt
grep "xkB/s" /tmp/.sarDEV.txt >/dev/null
if [ $? -eq 0 ];then
Trafficin=$(cat /tmp/.sarDEV.txt|awk '/Average/&&/eth0/{printf("%.2f",$5*8/1024)}')
Trafficout=$(cat /tmp/.sarDEV.txt|awk '/Average/&&/eth0/{printf("%.2f",$6*8/1024)}')
else
Trafficin=$(cat /tmp/.sarDEV.txt|awk '/Average/&&/eth0/{printf("%.2f",$5*8/1024/1024)}')
Trafficout=$(cat /tmp/.sarDEV.txt|awk '/Average/&&/eth0/{printf("%.2f",$6*8/1024/1024)}')
fi
#将采集数据通过cur,以useragent的形式传到接收端。接收端做法很简单,只需要打开nginx日志,然后nginx日志的格式只配置一个useragent的字段,这样就会将正行json格式记录了,参考配置: #log_format jsonlog escape=json '$http_user_agent';
#access_log logs/access_alarm.log jsonlog;
postData="{\"server\":\"$IP\",\"load\":$Load,\"swap\":$SwapUsed,\"mem\":$MemUsed,\"disk\":$DiskUsed,\"tcpconn\":$TcpConn,\"trafficin\":$Trafficin,\"trafficout\":$Trafficout,\"timestamp\":$Timestamp,
\"htime\":\"$Htime\"}"
curl -A "${postData}" -s --connect-timeout 5 --max-time 10 "${nodeperfApi}"
#告警判断
A_Load=$(echo "$Load"|awk '$1>15{printf "Load:%d\n",$1}') #负载大于15进行告警
A_MemUsed=$(echo "$MemUsed"|awk '$1>0.85{printf "MemUsed:%.3f\n",$1}') #内存使用率大于85%开始告警
A_SwapUsed=$(echo "$SwapUsed"|awk '$1>0.85{printf "SwapUsed:%.3f\n",$1}') #swap使用率大于85%开始告警
A_DiskUsed=$(echo "$DiskUsed"|awk '$1>0.9{printf "DiskUsed:%.3f\n",$1}') #磁盘使用率大于90%开始告警
echo -e "$A_Load $A_MemUsed $A_SwapUsed $A_DiskUsed" >$mail_content #将超出阀值的信息导出到临时文件
egrep "[A-Za-z0-9]" $mail_content >/dev/null
if [ $? -eq 0 ];then #判断导出的临时文件是否不为空
lastrunt=$(head -1 /tmp/nodealarm.tag)
ttimes=$(( 10#${Timestamp:0:10} - 10#$lastrunt ))
if [[ 10#$ttimes -gt 600 ]];then #判断距离上一次告警是否超过10分钟,超过之后才进行告警。
AlarmNotice
echo "${Timestamp:0:10}" >/tmp/nodealarm.tag
fi
echo "$Htime $alarmctx" >>/tmp/run.debug.log #将告警信息打印与本地日志
rm -f $mail_content
fi
}
init
CollectSysinfo