背景
公司有600多台服务器,打算写一个小程序,能一眼看见哪些服务器不在线。
大体思路是:
1、把所有服务器ip存进数据库,ping命令判断服务器是否在线
2、更新数据库中ip的状态
3、简单的web显示出来
4、优化程序,美观页面
一、python检测IP在线
fping命令,它是对一个文件的批量ping,瞬间完成的,如果ping不通,那就较慢,日常ping不通的毕竟是少数,所以这个非常适用。
这个命令需要安装,直接yum就行,yum install fping -y
创建fping.sh的shell脚本 #!/bin/bash rm -f result.txt cat ipmi_ping.txt | fping > result.txt
执行结果:
二、读取mysql数据
1、创建一张数据表,存放ip等信息
#创建一个表 create table ip_table( id int auto_increment, #id自增 ipaddress char(15) not null, #地址禁止为空 application char(24), status char(6), primary key(id) ); #插入部分数据 insert into ip_table values(id,'10.30.0.101','邮箱服务器','在线'); insert into ip_table values(id,'10.1.100.1','核心交换机','在线'); insert into ip_table values(id,'10.1.50.30','开发库','在线'); insert into ip_table values(id,'10.1.80.115','openstack控制节点','在线'); insert into ip_table values(id,'10.1.80.116','openstack计算节点','在线'); insert into ip_table values(id,'10.1.80.117','openstack块存储节点','在线'); commit;
2、python实现读取数据表中的内容,并写入到一个本地文件
# -*- coding:utf-8 -*- import pymysql def get_loan_number(file): connect = pymysql.connect( host="10.1.80.200", port=3306, user="alex", passwd="alex", db="ip", charset='utf8' ) print("写入中,请等待……") cursor = connect.cursor() #获取游标 sql = "select ipaddress from ip_table" #执行的sql cursor.execute(sql) #执行数据库操作 number = cursor.fetchall() #查询并返回所有结果 fp = open(file, "w") loan_count = 0 for loanNumber in number: loan_count += 1 fp.write(loanNumber[0] + " ") fp.close() cursor.close() #关闭指针对象 connect.close() #关闭数据库连接 print("写入完成,共写入%d条数据……" % loan_count) if __name__ == "__main__": file = r"loanNUmber.txt" get_loan_number(file)
二、执行fping脚本,并将结果输出到result文件
# -*- coding:utf-8 -*- import pymysql import os def get_loan_number(file): connect = pymysql.connect( host="localhost", port=3306, user="root", passwd="12345678", db="ip", charset='utf8' ) print("写入中,请等待……") cursor = connect.cursor() #获取游标 sql = "select ipaddress from ip_table" #执行的sql cursor.execute(sql) #执行数据库操作 number = cursor.fetchall() #查询并返回所有结果 fp = open(file, "w") loan_count = 0 for loanNumber in number: loan_count += 1 fp.write(loanNumber[0] + " ") fp.close() cursor.close() #关闭指针对象 connect.close() #关闭数据库连接 print("写入完成,共写入%d条数据……" % loan_count) f = os.system('sh /ping/fping.sh') if __name__ == "__main__": file = r"ipmi_ping.txt" get_loan_number(file)
三、读result.txt文件,将IP is unreachable的行提取更新状态‘不在线’
#!/usr/bin/python3 # -*- coding:utf-8 -*- import pymysql import os def get_loan_number(file): connect = pymysql.connect( host="localhost", port=3306, user="root", passwd="12345678", db="checkip", charset='utf8' ) print("写入中,请等待……") cursor = connect.cursor() #获取游标 sql = "select ipaddress from ip_table" #执行的sql cursor.execute(sql) #执行数据库操作 number = cursor.fetchall() #查询并返回所有结果 fp = open(file, "w") loan_count = 0 for loanNumber in number: loan_count += 1 fp.write(loanNumber[0] + " ") fp.close() print("写入完成,共写入%d条数据……" % loan_count) f = os.system('sh fping.sh') content = open('result.txt','r') first= content.read().split(' ') for i in range(0,len(first)-1): tmp = first[i] ip = tmp[:tmp.index('is')-1] status = '在线' if 'unreachable' in tmp: status = '离线' cursor.execute('update ip_table set status ="%s" where ipaddress ="%s"'%(status,ip)) connect.commit() content.close() cursor.close() #关闭指针对象 connect.close() #关闭数据库连接 if __name__ == "__main__": file = r"ipmi_ping.txt" get_loan_number(file)
此时已经可以在数据库中看见status发送了变化。
四、设置get_loan_number每秒执行
#!/usr/bin/python3 # -*- coding:utf-8 -*- import pymysql import os import time def get_loan_number(file): connect = pymysql.connect( host="localhost", port=3306, user="root", passwd="12345678", db="checkip", charset='utf8' ) cursor = connect.cursor() #获取游标 sql = "select ipaddress from ip_table" #执行的sql cursor.execute(sql) #执行数据库操作 number = cursor.fetchall() #查询并返回所有结果 fp = open(file, "w") loan_count = 0 for loanNumber in number: loan_count += 1 fp.write(loanNumber[0] + " ") fp.close() f = os.system('sh fping.sh >> checkip.log 2>&1') content = open('result.txt','r') first= content.read().split(' ') #通过指定分隔符对字符串进行切片 for i in range(0,len(first)-1): tmp = first[i] ip = tmp[:tmp.index('is')-1] status = '在线' if 'unreachable' in tmp: status = '离线' cursor.execute('update ip_table set status ="%s" where ipaddress ="%s"'%(status,ip)) connect.commit() content.close() cursor.close() #关闭指针对象 connect.close() #关闭数据库连接 while True: get_loan_number(r"ipmi_ping.txt") time.sleep(3)
五、设计web提取mysql数据
这里我用了flask框架,因为简单好用。
首先安装python第三方模块:
pip3 install flask pip3 install flask_bootstrap pip3 install pymysql
建立base.html
{% extends "bootstrap/base.html" %} {% block title %}Flask{% endblock %} {% block navbar %} <div class="navbar navbar-inverse" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">PMSystem</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li><a href="/">主机在线平台</a></li> </ul> </div> </div> </div> {% endblock %} {% block content %} <div class="container"> {% block page_content %}{% endblock %} </div> {% endblock %}
建立index.html
{% extends "base.html" %} {% block title %}主机平台{% endblock %} {% block page_content %} <table class="table table-bordered"> <tr> <th>序号</th> <th>IP地址</th> <th>服务</th> <th>是否在线</th> </tr> {% for i in u %} <tr> <td>{{ i[0] }}</td> <td>{{ i[1] }}</td> <td>{{ i[2] }}</td> <td>{{ i[3] }}</td> </tr> {% endfor %} </table> {% endblock %}
建立app.py
from flask import Flask from flask import render_template from flask_bootstrap import Bootstrap import pymysql app = Flask(__name__) bootstrap = Bootstrap(app) @app.route('/') def index(): conn = pymysql.connect(host='10.1.80.110', user='alex', password='alex', db='checkip', charset='utf8') cur = conn.cursor() sql = "SELECT * FROM ip_table" cur.execute(sql) u = cur.fetchall() conn.close() return render_template('index.html',u=u) if __name__ == '__main__': app.run(host='0.0.0.0',debug=True)
运行一下程序:
初步实现了需求。
六、设置后台执行
nohup /python3/bin/python3.5 -u ping.py >> ping.log nohup /python3/bin/python3.5 -u app.py >> app.log 2>&1 &