Linux服务器系统监控框架与MSN、E-mail、手机短信报警的实现

Server 林涛 1208℃ 0评论

最近,在原有的“Linux服务器系统监控程序”基础上,完善了HTTP、TCP、MySQL主动监控与MSN、E-mail、手机短信报警。监控程序以shell和PHP程序编写,以下为主要框架与部分代码:

一、系统监控接口程序(interface.php)具有的报警方式
1、MSN实时报警
①、监控程序每次检测到故障存在、或者故障恢复,都会发送短消息到管理员的MSN。
点击在新窗口中浏览此图片

点击在新窗口中浏览此图片

发送MSN短消息用了一个PHP类:sendMsg,使用该PHP类发消息,必须将发送、接收双方的MSN加为联系人,发送中文时,先用iconv将字符集转为UTF-8:

引用
$sendMsg->sendMessage(iconv(“GBK”, “UTF-8”, $message), ‘Times New Roman’, ‘008000’);

2、手机短信报警
①、工作日早上10点之前,晚上6点之后,以及周六、周日,监控程序检测到故障,会调用手机短信接口,发送短信给管理员的手机。
②、如果监控程序多次检测到同一台服务器的同一类故障,只会在第一次检测到故障时发送一条“故障报警”短信。服务器故障恢复后,监控程序会再发送一条“故障恢复”短信。

如果没有手机短信网关接口,可以试试中国移动通信的www.139.com邮箱,具有免费的邮件到达手机短信通知功能,可以将收到的邮件标题以短信的形式发送到手机上。


3、电子邮件报警
①、如果监控程序多次检测到同一台服务器的同一类故障,只会在第一次检测到故障时发送一封“故障报警”邮件。服务器故障恢复后,监控程序会再发送一封“故障恢复”邮件。

系统监控接口程序interface.php(核心部分,仅提供部分代码):

  1. <?php
  2. //HTTP服务器监控
  3. if (htmlspecialchars($_POST[“menu”]) == “http”)
  4. {
  5. $date = htmlspecialchars($_POST[“date”]);
  6. $ip = htmlspecialchars($_POST[“ip”]);
  7. $port = htmlspecialchars($_POST[“port”]);
  8. $status = htmlspecialchars($_POST[“status”]);//状态,0表示无法访问,1表示正常,2表示无法访问但能ping通
  9. //…下一步处理(省略)…
  10. }
  11. //TCP服务器监控
  12. if (htmlspecialchars($_POST[“menu”]) == “tcp”)
  13. {
  14. $date = htmlspecialchars($_POST[“date”]);
  15. $ip = htmlspecialchars($_POST[“ip”]);
  16. $port = htmlspecialchars($_POST[“port”]);
  17. $status = htmlspecialchars($_POST[“status”]);//状态,0表示无法访问,1表示正常,2表示无法访问但能ping通
  18. //…下一步处理(省略)…
  19. }
  20. //MySQL服务器监控
  21. if (htmlspecialchars($_POST[“menu”]) == “mysql”)
  22. {
  23. $date = htmlspecialchars($_POST[“date”]);
  24. $ip = htmlspecialchars($_POST[“ip”]);
  25. $port = htmlspecialchars($_POST[“port”]);
  26. $abstract = htmlspecialchars($_POST[“abstract”]);//故障摘要(必须为全角)
  27. $info = htmlspecialchars($_POST[“info”]);//故障详细描述
  28. $failback = htmlspecialchars($_POST[“failback”]);//如果服务器存活,此处接收的值为active
  29. //…下一步处理(省略)…
  30. }
  31. ?>

二、主动探测监控(“监控机”主动探测“被监控机”)
1、HTTP服务器监控
脚本:/data0/monitor/http.sh

引用
#!/bin/sh
LANG=C

#被监控服务器、端口列表
server_all_list=(\
192.168.1.1:80 \
192.168.1.2:80 \
192.168.1.3:80 \
)

date=$(date -d “today” +”%Y-%m-%d_%H:%M:%S”)

#采用HTTP POST方式发送检测信息给接口程序interface.php,接口程序负责分析信息,决定是否发送报警MSN消息、手机短信、电子邮件。
send_msg_to_interface()
{
/usr/bin/curl -m 600 -d menu=http -d date=$date -d ip=$server_ip -d port=$server_port -d status=$status http://127.0.0.1:8888/interface.php
}

server_all_len=${#server_all_list[*]}
i=0
while  [ $i -lt $server_all_len ]
do
server_ip=$(echo ${server_all_list[$i]} | awk -F ‘:’ ‘{print $1}’)
server_port=$(echo ${server_all_list[$i]} | awk -F ‘:’ ‘{print $2}’)
if curl -m 10 -G http://${server_all_list[$i]}/ > /dev/null 2>&1
then
#status:    0,http down    1,http ok    2,http down but ping ok
status=1
echo “服务器${server_ip},端口${server_port}能够正常访问!”
else
if curl -m 30 -G http://${server_all_list[$i]}/ > /dev/null 2>&1
then
status=1
echo “服务器${server_ip},端口${server_port}能够正常访问!”
else
if ping -c 1 $server_ip > /dev/null 2>&1
then
status=2
echo “服务器${server_ip},端口${server_port}无法访问,但是能够Ping通!”
else
status=0
echo “服务器${server_ip},端口${server_port}无法访问,并且无法Ping通!”
fi
fi
fi
send_msg_to_interface
let i++
done

 


2、TCP服务器监控
脚本:/data0/monitor/tcp.sh

引用
#!/bin/sh
LANG=C

#被监控服务器、端口列表
server_all_list=(\
192.168.1.4:11211 \
192.168.1.5:11211 \
192.168.1.6:25 \
192.168.1.7:25 \
)

date=$(date -d “today” +”%Y-%m-%d_%H:%M:%S”)

#采用HTTP POST方式发送检测信息给接口程序interface.php,接口程序负责分析信息,决定是否发送报警MSN消息、手机短信、电子邮件。
send_msg_to_interface()
{
/usr/bin/curl -m 600 -d menu=tcp -d date=$date -d ip=$server_ip -d port=$server_port -d status=$status http://127.0.0.1:8888/interface.php
}

server_all_len=${#server_all_list[*]}
i=0
while  [ $i -lt $server_all_len ]
do
server_ip=$(echo ${server_all_list[$i]} | awk -F ‘:’ ‘{print $1}’)
server_port=$(echo ${server_all_list[$i]} | awk -F ‘:’ ‘{print $2}’)
if nc -vv -z -w 3 $server_ip $server_port > /dev/null 2>&1
then
#status:    0,http down    1,http ok    2,http down but ping ok
status=1
echo “服务器${server_ip},端口${server_port}能够正常访问!”
else
if nc -vv -z -w 10 $server_ip $server_port > /dev/null 2>&1
then
status=1
echo “服务器${server_ip},端口${server_port}能够正常访问!”
else
if ping -c 1 $server_ip > /dev/null 2>&1
then
status=2
echo “服务器${server_ip},端口${server_port}无法访问,但是能够Ping通!”
else
status=0
echo “服务器${server_ip},端口${server_port}无法访问,并且无法Ping通!”
fi
fi
fi
send_msg_to_interface
let i++
done

 


3、MySQL服务器监控
①、MySQL是否能够连接
②、MySQL是否发生表损坏等错误
③、MySQL活动连接数是否过多
④、MySQL从库是否同步正常
⑤、MySQL从库同步延迟时间是否过大
脚本:/data0/monitor/mysql.php

  1. <?php
  2. //$server_list[]=”服务器地址:端口:帐号:密码”;
  3. $server_list[]=”192.168.1.11:3306:root:password”;
  4. $server_list[]=”192.168.1.12:3306:root:password”;
  5. $server_list[]=”192.168.1.13:3306:root:password”;
  6. $database=”mysql”;
  7. $curl = new Curl_Class();
  8. foreach ($server_list as $server) {
  9. $status=1;//初始化,正常状态
  10. unset($data);
  11. $data[“menu”] = “mysql”;
  12. $data[“info”] = “”;
  13. list($data[“ip”], $data[“port”], $username, $password) = explode(“:”, $server);
  14. $connect = @mysql_connect($data[“ip”].”:”.$data[“port”], $username, $password);
  15. if(! $connect)
  16. {
  17. $status=0;
  18. $data[“info”] = $data[“info”] . “无法连接MySQL服务器\r\n”;
  19. }
  20. $select = @mysql_select_db($database, $connect);
  21. $result = @mysql_query(“show slave status”);
  22. $rs_slave = @mysql_fetch_array($result);
  23. $result = @mysql_query(“show global status like ‘Threads_running'”);
  24. $rs_threads = @mysql_fetch_array($result);
  25. if($rs_slave[“Slave_SQL_Running”] == “No”)
  26. {
  27. $status=0;//故障状态
  28. $data[“abstract”] = “从库不同步”;
  29. $data[“info”] = $data[“info”] . “Slave_SQL_Running = No\r\n”;
  30. }
  31. if($rs_slave[“Slave_IO_Running”] == “No”)
  32. {
  33. $status=0;
  34. $data[“abstract”] = “从库不同步”;
  35. $data[“info”] = $data[“info”] . “Slave_IO_Running = No\r\n”;
  36. }
  37. if($rs_slave[“Last_Error”] != “”)
  38. {
  39. $status=0;
  40. $data[“abstract”] = “从库同步出错”;
  41. $data[“info”] = $data[“info”] . “Last_Error = “.substr($rs_slave[“Last_Error”], 0, 40).”\r\n”;
  42. }
  43. if($rs_slave[“Seconds_Behind_Master”] > 180)
  44. {
  45. $status=0;
  46. $data[“abstract”] = “从库同步延迟时间高达”.$rs_slave[“Seconds_Behind_Master”].”秒”;
  47. $data[“info”] = $data[“info”] . “Seconds_Behind_Master = “.$rs_slave[“Seconds_Behind_Master”].”\r\n”;
  48. }
  49. if($rs_threads[“Value”] > 60)
  50. {
  51. $status=0;
  52. $data[“abstract”] = “活动连接数多达”.$rs_threads[“Value”];
  53. $data[“info”] = $data[“info”] . “Threads_running = “.$rs_threads[“Value”].”\r\n”;
  54. }
  55. $data[“date”] = date(“Y-m-d_H:i:s”);
  56. if($status == 0)
  57. {
  58. $post = @$curl->post(“http://127.0.0.1:8888/interface.php”, $data);
  59. echo “MySQL服务器“”.$data[“ip”].”:”.$data[“port”].””发生故障!\n”;
  60. print_r($post);
  61. }
  62. else
  63. {
  64. $data[“failback”] = “active”;//服务器正常,发送通知信息
  65. $post = @$curl->post(“http://127.0.0.1:8888/interface.php”, $data);
  66. echo “MySQL服务器“”.$data[“ip”].”:”.$data[“port”].””运行正常!\n”;
  67. print_r($post);
  68. }
  69. }
  70. /**
  71. *********************************************************************
  72. * Curl_Class :curl 类
  73. *********************************************************************/
  74. class Curl_Class
  75. {
  76. function Curl_Class()
  77. {
  78. return true;
  79. }
  80. function execute($method, $url, $fields = ”, $userAgent = ”, $httpHeaders = ”,
  81. $username = ”, $password = ”)
  82. {
  83. $ch = Curl_Class::create();
  84. if (false === $ch)
  85. {
  86. return false;
  87. }
  88. if (is_string($url) && strlen($url))
  89. {
  90. $ret = curl_setopt($ch, CURLOPT_URL, $url);
  91. }
  92. else
  93. {
  94. return false;
  95. }
  96. //是否显示头部信息
  97. curl_setopt($ch, CURLOPT_HEADER, false);
  98. //
  99. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  100. if ($username != ”)
  101. {
  102. curl_setopt($ch, CURLOPT_USERPWD, $username . ‘:’ . $password);
  103. }
  104. $method = strtolower($method);
  105. if (‘post’ == $method)
  106. {
  107. curl_setopt($ch, CURLOPT_POST, true);
  108. if (is_array($fields))
  109. {
  110. $sets = array();
  111. foreach ($fields as $key => $val)
  112. {
  113. $sets[] = $key . ‘=’ . urlencode($val);
  114. }
  115. $fields = implode(‘&’, $sets);
  116. }
  117. curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
  118. }
  119. else
  120. if (‘put’ == $method)
  121. {
  122. curl_setopt($ch, CURLOPT_PUT, true);
  123. }
  124. //curl_setopt($ch, CURLOPT_PROGRESS, true);
  125. //curl_setopt($ch, CURLOPT_VERBOSE, true);
  126. //curl_setopt($ch, CURLOPT_MUTE, false);
  127. curl_setopt($ch, CURLOPT_TIMEOUT, 600);
  128. if (strlen($userAgent))
  129. {
  130. curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
  131. }
  132. if (is_array($httpHeaders))
  133. {
  134. curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeaders);
  135. }
  136. $ret = curl_exec($ch);
  137. if (curl_errno($ch))
  138. {
  139. curl_close($ch);
  140. return array(curl_error($ch), curl_errno($ch));
  141. }
  142. else
  143. {
  144. curl_close($ch);
  145. if (!is_string($ret) || !strlen($ret))
  146. {
  147. return false;
  148. }
  149. return $ret;
  150. }
  151. }
  152. function post($url, $fields, $userAgent = ”, $httpHeaders = ”, $username = ”,
  153. $password = ”)
  154. {
  155. $ret = Curl_Class::execute(‘POST’, $url, $fields, $userAgent, $httpHeaders, $username,
  156. $password);
  157. if (false === $ret)
  158. {
  159. return false;
  160. }
  161. if (is_array($ret))
  162. {
  163. return false;
  164. }
  165. return $ret;
  166. }
  167. function get($url, $userAgent = ”, $httpHeaders = ”, $username = ”, $password =
  168. ”)
  169. {
  170. $ret = Curl_Class::execute(‘GET’, $url, ”, $userAgent, $httpHeaders, $username,
  171. $password);
  172. if (false === $ret)
  173. {
  174. return false;
  175. }
  176. if (is_array($ret))
  177. {
  178. return false;
  179. }
  180. return $ret;
  181. }
  182. function create()
  183. {
  184. $ch = null;
  185. if (!function_exists(‘curl_init’))
  186. {
  187. return false;
  188. }
  189. $ch = curl_init();
  190. if (!is_resource($ch))
  191. {
  192. return false;
  193. }
  194. return $ch;
  195. }
  196. }
  197. ?>

4、主动监控守护进程
脚本:/data0/monitor/monitor.sh

引用
#!/bin/sh
while true
do
/bin/sh /data0/monitor/http.sh > /dev/null 2>&1
/bin/sh /data0/monitor/tcp.sh > /dev/null 2>&1
/usr/local/php/bin/php /data0/monitor/mysql.php > /dev/null 2>&1
sleep 10
done

启动主动监控守护进程:

/usr/bin/nohup /bin/sh /data0/monitor/monitor.sh 2>&1 > /dev/null &

 


三、被动报告监控(“被监控机”采集数据发送给“监控机”)
1、磁盘空间使用量监控
2、磁盘Inode使用量监控
3、Swap交换空间使用量监控
4、系统负载监控
5、Apache进程数监控

被动监控这部分,在我的文章《写完“Linux服务器监控系统 ServMon V1.1” 》中已经实现,就不再详细写出。

 

来自:http://blog.s135.com/post/354/

如需转载请注明: 转载自26点的博客

本文链接地址: Linux服务器系统监控框架与MSN、E-mail、手机短信报警的实现

转载请注明:26点的博客 » Linux服务器系统监控框架与MSN、E-mail、手机短信报警的实现

喜欢 (0)
发表我的评论
取消评论

表情