first commit
This commit is contained in:
commit
ba848e218d
1001 changed files with 152333 additions and 0 deletions
328
Python/用Python写一个简单的监控系统-51reboot.html
Normal file
328
Python/用Python写一个简单的监控系统-51reboot.html
Normal file
|
@ -0,0 +1,328 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="tool" content="leanote-desktop-app">
|
||||
<title>用Python写一个简单的监控系统 - 51reboot</title>
|
||||
<style>
|
||||
|
||||
*{font-family:"lucida grande","lucida sans unicode",lucida,helvetica,"Hiragino Sans GB","Microsoft YaHei","WenQuanYi Micro Hei",sans-serif;}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/*公用文字样式*/
|
||||
h1{font-size:30px}h2{font-size:24px}h3{font-size:18px}h4{font-size:14px}
|
||||
.note-container{
|
||||
width:850px;
|
||||
margin:auto;
|
||||
padding: 10px 20px;
|
||||
box-shadow: 1px 1px 10px #eee;
|
||||
}
|
||||
#title {
|
||||
margin: 0;
|
||||
}
|
||||
table {
|
||||
margin-bottom: 16px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table th, table td {
|
||||
padding: 6px 13px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
table th {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table tr {
|
||||
background-color: none;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
table tr:nth-child(2n) {
|
||||
background-color: rgb(247, 247, 249);
|
||||
}
|
||||
.mce-item-table, .mce-item-table td, .mce-item-table th, .mce-item-table caption {
|
||||
border: 1px solid #ddd;
|
||||
border-collapse: collapse;
|
||||
padding: 6px 13px;
|
||||
}
|
||||
blockquote {
|
||||
border-left-width:10px;
|
||||
background-color:rgba(128,128,128,0.05);
|
||||
border-top-right-radius:5px;
|
||||
border-bottom-right-radius:5px;
|
||||
padding:15px 20px;
|
||||
border-left:5px solid rgba(128,128,128,0.075);
|
||||
}
|
||||
blockquote p {
|
||||
margin-bottom:1.1em;
|
||||
font-size:1em;
|
||||
line-height:1.45
|
||||
}
|
||||
blockquote ul:last-child,blockquote ol:last-child {
|
||||
margin-bottom:0
|
||||
}
|
||||
pre {
|
||||
padding: 18px;
|
||||
background-color: #f7f7f9;
|
||||
border: 1px solid #e1e1e8;
|
||||
border-radius: 3px;
|
||||
display: block;
|
||||
}
|
||||
code {
|
||||
padding: 2px 4px;
|
||||
font-size: 90%;
|
||||
color: #c7254e;
|
||||
white-space: nowrap;
|
||||
background-color: #f9f2f4;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.footnote {
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
top: -0.5em;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
hr {
|
||||
margin:2em 0
|
||||
}
|
||||
img {
|
||||
max-width:100%
|
||||
}
|
||||
pre {
|
||||
word-break:break-word
|
||||
}
|
||||
p,pre,pre.prettyprint,blockquote {
|
||||
margin:0 0 1.1em
|
||||
}
|
||||
hr {
|
||||
margin:2em 0
|
||||
}
|
||||
img {
|
||||
max-width:100%
|
||||
}
|
||||
.sequence-diagram,.flow-chart {
|
||||
text-align:center;
|
||||
margin-bottom:1.1em
|
||||
}
|
||||
.sequence-diagram text,.flow-chart text {
|
||||
font-size:15px !important;
|
||||
font-family:"Source Sans Pro",sans-serif !important
|
||||
}
|
||||
.sequence-diagram [fill="#ffffff"],.flow-chart [fill="#ffffff"] {
|
||||
fill:#f6f6f6
|
||||
}
|
||||
.sequence-diagram [stroke="#000000"],.flow-chart [stroke="#000000"] {
|
||||
stroke:#3f3f3f
|
||||
}
|
||||
.sequence-diagram text[stroke="#000000"],.flow-chart text[stroke="#000000"] {
|
||||
stroke:none
|
||||
}
|
||||
.sequence-diagram [fill="#000"],.flow-chart [fill="#000"],.sequence-diagram [fill="#000000"],.flow-chart [fill="#000000"],.sequence-diagram [fill="black"],.flow-chart [fill="black"] {
|
||||
fill:#3f3f3f
|
||||
}
|
||||
ul,ol {
|
||||
margin-bottom:1.1em
|
||||
}
|
||||
ul ul,ol ul,ul ol,ol ol {
|
||||
margin-bottom:1.1em
|
||||
}
|
||||
kbd {
|
||||
padding:.1em .6em;
|
||||
border:1px solid rgba(63,63,63,0.25);
|
||||
-webkit-box-shadow:0 1px 0 rgba(63,63,63,0.25);
|
||||
box-shadow:0 1px 0 rgba(63,63,63,0.25);
|
||||
font-size:.7em;
|
||||
font-family:sans-serif;
|
||||
background-color:#fff;
|
||||
color:#333;
|
||||
border-radius:3px;
|
||||
display:inline-block;
|
||||
margin:0 .1em;
|
||||
white-space:nowrap
|
||||
}
|
||||
.toc ul {
|
||||
list-style-type:none;
|
||||
margin-bottom:15px
|
||||
}
|
||||
</style>
|
||||
<!-- 该css供自定义样式 -->
|
||||
<link href="../leanote-html.css" rel="stylesheet">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="note-container">
|
||||
<h1 class="title" id="leanote-title">用Python写一个简单的监控系统 - 51reboot</h1>
|
||||
<div class="content-html" id="leanote-content"><p>市面上有很多开源的监控系统:Cacti、nagios、zabbix。感觉都不符合我的需求,为什么不自己做一个呢</p><p>用Python两个小时徒手撸了一个简易的监控系统,给大家分享一下,希望能对大家有所启发</p><p>首先数据库建表</p><p>建立一个数据库“falcon”,建表语句如下:</p><pre id="leanote_ace_1479693920366_0" class="brush:python ace-tomorrow" data-mce-style="line-height: 1.5; font-size: 14px; height: 231px;">CREATE TABLE `stat` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`host` varchar(256) DEFAULT NULL,
|
||||
`mem_free` int(11) DEFAULT NULL,
|
||||
`mem_usage` int(11) DEFAULT NULL,
|
||||
`mem_total` int(11) DEFAULT NULL,
|
||||
`load_avg` varchar(128) DEFAULT NULL,
|
||||
`time` bigint(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `host` (`host`(255))
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;</pre><p>首先我们设计一个web服务,实现如下功能:</p><ol><li>完成监控页面展示</li><li>接受POST提交上来的数据</li><li>提供json数据GET接口</li></ol><p>目录结构如下:</p><pre id="leanote_ace_1479795467113_0" class="ace-tomorrow">web
|
||||
├── flask_web.py
|
||||
└── templates
|
||||
└── mon.html</pre><p>flask_web.py</p><pre id="leanote_ace_1479693978975_0" class="brush:python ace-tomorrow" data-mce-style="line-height: 1.5; font-size: 14px; height: 693px;">import MySQLdb as mysql
|
||||
import json
|
||||
from flask import Flask, request, render_template
|
||||
app = Flask(__name__)
|
||||
db = mysql.connect(user="reboot", passwd="reboot123", \
|
||||
db="falcon", charset="utf8")
|
||||
db.autocommit(True)
|
||||
c = db.cursor()
|
||||
|
||||
@app.route("/", methods=["GET", "POST"])
|
||||
def hello():
|
||||
sql = ""
|
||||
if request.method == "POST":
|
||||
data = request.json
|
||||
try:
|
||||
sql = "INSERT INTO `stat` (`host`,`mem_free`,`mem_usage`,`mem_total`,`load_avg`,`time`) VALUES('%s', '%d', '%d', '%d', '%s', '%d')" % (data['Host'], data['MemFree'], data['MemUsage'], data['MemTotal'], data['LoadAvg'], int(data['Time']))
|
||||
ret = c.execute(sql)
|
||||
except mysql.IntegrityError:
|
||||
pass
|
||||
return "OK"
|
||||
else:
|
||||
return render_template("mon.html")
|
||||
|
||||
@app.route("/data", methods=["GET"])
|
||||
def getdata():
|
||||
c.execute("SELECT `time`,`mem_usage` FROM `stat`")
|
||||
ones = [[i[0]*1000, i[1]] for i in c.fetchall()]
|
||||
return "%s(%s);" % (request.args.get('callback'), json.dumps(ones))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=8888, debug=True)</pre><p>这个template页面是我抄的highstock的示例,mon.html</p><p>简单起见我们只展示mem_usage信息到页面上</p><pre id="leanote_ace_1479695091757_0" class="ace-tomorrow brush:html">
|
||||
<title>51reboot.com</title>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Highstock Example</title>
|
||||
|
||||
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
||||
<style type="text/css">
|
||||
${demo.css}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$.getJSON('/data?callback=?', function (data) {
|
||||
|
||||
// Create the chart
|
||||
$('#container').highcharts('StockChart', {
|
||||
|
||||
rangeSelector: {
|
||||
inputEnabled: $('#container').width() > 480,
|
||||
selected: 1
|
||||
},
|
||||
|
||||
title: {
|
||||
text: '51Reboot.com'
|
||||
},
|
||||
|
||||
series: [{
|
||||
name: '51Reboot.com',
|
||||
data: data,
|
||||
type: 'spline',
|
||||
tooltip: {
|
||||
valueDecimals: 2
|
||||
}
|
||||
}]
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/highstock/2.0.4/highstock.js"></script>
|
||||
<script src="http://code.highcharts.com/modules/exporting.js"></script>
|
||||
|
||||
|
||||
<div id="container" style="height: 400px"></div>
|
||||
</body>
|
||||
</html></pre><p>python flask_web.py 监听在8888端口上</p><p>我们需要做一个agent来采集数据,并上传数据库</p><p>moniItems.py</p><pre id="leanote_ace_1479694477128_0" class="brush:python ace-tomorrow">#!/usr/bin/env python
|
||||
import inspect
|
||||
import time
|
||||
import urllib, urllib2
|
||||
import json
|
||||
import socket
|
||||
|
||||
class mon:
|
||||
def __init__(self):
|
||||
self.data = {}
|
||||
|
||||
def getTime(self):
|
||||
return str(int(time.time()) + 8 * 3600)
|
||||
|
||||
def getHost(self):
|
||||
return socket.gethostname()
|
||||
|
||||
def getLoadAvg(self):
|
||||
with open('/proc/loadavg') as load_open:
|
||||
a = load_open.read().split()[:3]
|
||||
return ','.join(a)
|
||||
|
||||
def getMemTotal(self):
|
||||
with open('/proc/meminfo') as mem_open:
|
||||
a = int(mem_open.readline().split()[1])
|
||||
return a / 1024
|
||||
|
||||
def getMemUsage(self, noBufferCache=True):
|
||||
if noBufferCache:
|
||||
with open('/proc/meminfo') as mem_open:
|
||||
T = int(mem_open.readline().split()[1])
|
||||
F = int(mem_open.readline().split()[1])
|
||||
B = int(mem_open.readline().split()[1])
|
||||
C = int(mem_open.readline().split()[1])
|
||||
return (T-F-B-C)/1024
|
||||
else:
|
||||
with open('/proc/meminfo') as mem_open:
|
||||
a = int(mem_open.readline().split()[1]) - int(mem_open.readline().split()[1])
|
||||
return a / 1024
|
||||
|
||||
def getMemFree(self, noBufferCache=True):
|
||||
if noBufferCache:
|
||||
with open('/proc/meminfo') as mem_open:
|
||||
T = int(mem_open.readline().split()[1])
|
||||
F = int(mem_open.readline().split()[1])
|
||||
B = int(mem_open.readline().split()[1])
|
||||
C = int(mem_open.readline().split()[1])
|
||||
return (F+B+C)/1024
|
||||
else:
|
||||
with open('/proc/meminfo') as mem_open:
|
||||
mem_open.readline()
|
||||
a = int(mem_open.readline().split()[1])
|
||||
return a / 1024
|
||||
|
||||
def runAllGet(self):
|
||||
#自动获取mon类里的所有getXXX方法,用XXX作为key,getXXX()的返回值作为value,构造字典
|
||||
for fun in inspect.getmembers(self, predicate=inspect.ismethod):
|
||||
if fun[0][:3] == 'get':
|
||||
self.data[fun[0][3:]] = fun[1]()
|
||||
return self.data
|
||||
|
||||
if __name__ == "__main__":
|
||||
while True:
|
||||
m = mon()
|
||||
data = m.runAllGet()
|
||||
print data
|
||||
req = urllib2.Request("http://51reboot.com:8888", json.dumps(data), {'Content-Type': 'application/json'})
|
||||
f = urllib2.urlopen(req)
|
||||
response = f.read()
|
||||
print response
|
||||
f.close()
|
||||
time.sleep(60)</pre><p>nohup python moniItems.py >/dev/null 2>&1 & 运行起来</p><p><img id="__LEANOTE_D_IMG_1479695175380" src="http://192.168.56.4:9000/api/file/getImage?fileId=5833f84623eeeb0f8f0000c4" alt="chart" data-mce-src="http://192.168.56.4:9000/api/file/getImage?fileId=5833f84623eeeb0f8f0000c4"><img src="http://192.168.56.4:9000/api/file/getImage?fileId=5833f84623eeeb0f8f0000c5" alt="" data-mce-src="http://192.168.56.4:9000/api/file/getImage?fileId=5833f84623eeeb0f8f0000c5"></p></div>
|
||||
</div>
|
||||
|
||||
<!-- 该js供其它处理 -->
|
||||
<script src="../leanote-html.js"></script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue