有几个朋友一直问我,页面的实时监控咋做。

他们在做idc节点的监控,我推荐用smokeping和zabbix接口的方式测试。但那哥们挺执着的,非要好看点的图表~

关于运维业务的实时监控,我做过两套方案:

第一种是用websocket的方式,这个时效性最强,也最快最及时。第二套用的是节点自己插入数据库,或者是通过接口插入到数据库,然后页面通过刷新来取出数据库里面的值,来渲染页面。。。。

这两个都有点开发比较麻烦,维护也麻烦。。。正好我这段时间在搞saltstack,一直想利用mq的速度来做小型的监控方案。。。

下面的小例子,就可以实现。。。。

我们先用cmd.run实现下,再用grains采集信息。。。


先放出一个小demo~

原文地址:http://rfyiamcool.blog.51cto.com/1030776/1266437

很简单的实现过程

1.  通过saltstack modules 和grains 收集信息

2.  然后放到页面中


今天找个时间写出来.


104806331.jpg



安装flask  然后直接跑就行了~

102420141.jpg


先简单写了个点击刷新信息页面~


这里缺一个bootstrap的css  需要大家自己引入。。。

放到同一个目录下就行啦~


#!/usr/bin/env python
#coding=utf-8
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
from flask import Flask,url_for,request,render_template,redirect,abort,escape,session
from werkzeug import secure_filename
import os
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
print __name__
app = Flask(__name__)
app.secret_key = 'hello'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
@app.route('/')
def index():
    p=os.popen('salt \'*\' grains.item psnum netnum').read()
    p=os.popen('salt \* cmd.run \'netstat -an|wc -l\'').read()
    return '''
<!DOCTYPE html>
<!-- saved from url=(0053)http://www.bootcss.com/examples/marketing-narrow.html -->
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <title>xiaorui.cc</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">
    <!-- Le styles -->
    <link href="bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
      body {
        padding-top: 20px;
        padding-bottom: 40px;
      }
      /* Custom container */
      .container-narrow {
        margin: 0 auto;
        max-width: 700px;
      }
      .container-narrow > hr {
        margin: 30px 0;
      }
      /* Main marketing message and sign up button */
      .jumbotron {
        margin: 60px 0;
        text-align: center;
      }
      .jumbotron h1 {
        font-size: 72px;
        line-height: 1;
      }
      .jumbotron .btn {
        font-size: 21px;
        padding: 14px 24px;
      }
      /* Supporting marketing content */
      .marketing {
        margin: 60px 0;
      }
      .marketing p + h4 {
        margin-top: 28px;
      }
    </style>
    <link href="http://cdnjs.bootcss.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap-responsive.min.css" rel="stylesheet">
    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
      <script src="//cdnjs.bootcss.com/ajax/libs/html5shiv/3.6.2/html5shiv.js"></script>
    <![endif]-->
    <!-- Fav and touch icons -->
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="http://www.bootcss.com/assets/ico/apple-touch-icon-144-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://www.bootcss.com/assets/ico/apple-touch-icon-114-precomposed.png">
      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://www.bootcss.com/assets/ico/apple-touch-icon-72-precomposed.png">
                    <link rel="apple-touch-icon-precomposed" href="http://www.bootcss.com/assets/ico/apple-touch-icon-57-precomposed.png">
                                   <link rel="shortcut icon" href="http://www.bootcss.com/assets/ico/favicon.png">
  <script>window["_GOOG_TRANS_EXT_VER"] = "1";</script></head>
  <body>
    <div class="container-narrow">
      <div class="masthead">
        <ul class="nav nav-pills pull-right">
          <li class="active"><a href="http://www.bootcss.com/examples/marketing-narrow.html#">Home</a></li>
          <li><a href="http://www.bootcss.com/examples/marketing-narrow.html#">命令推送</a></li>
          <li><a href="http://www.bootcss.com/examples/marketing-narrow.html#">图标监控</a></li>
        </ul>
        <h3 class="muted">实时监控</h3>
      </div>
      <hr>
      <div class="jumbotron">
        <pre>%s</pre>
        <a class="btn btn-large btn-success" href="http://10.10.10.66:8888">刷新</a>
      </div>
      <hr>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
      <hr>
      <div class="footer">
        <h4>by xiaorui.cc</h4>
      </div>
    </div> <!-- /container -->
    <!-- Le javascript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
</body></html>
'''%p
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
@app.route('/user/<username>')
def show_username(username):
    return username
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
@app.route('/post/<int:post_id>')
def show_post(post_id):
    return 'post_id:%d' % post_id
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
@app.route('/index/')
def test_session():
    if 'username' in session:
        return 'logged in as %s' % escape(session['username'])
    return redirect(url_for('login'))
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('test_session'))
    else:
        return
'''
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
<form action="/login/" method="post">
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
<input type=text name=username>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
<input type=submit value=login>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
</form>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
'''
@app.route('/setcookie')
def set_cookie():
    if 'num' in request.cookies:
        count = int(request.cookies['num']) + 1
    else:
        count = 0
    response = app.make_response(str(count))
    response.set_cookie('num',value=count,max_age=None,expires=None,domain=None)
    return response
if __name__ == "__main__":
    app.run(host="10.10.10.66",port=8888,debug=True)




xiaorui.cc

花了半小时把图表展现给更新出来,这个只是简单的demo。

让大家体验下 数据填充图表的做法。

后端数据都是静态的,下次再写个动态的渲染。

关于这些业务数据,大家可以把执行结果往库里仍,然后从库里拉出来。可以用saltstack的returners把数据搞到mysql或者mongodb。

或者是放一个全局的变量,把数据往list的最后面放,满12个数值话,开始清除第一个,然后把数据往后放。。。。

或者是把saltstack的执行结果放到文本里面,两个列  一个是时间轴 一个是数据轴。然后搞出来,渲染到前端。

总之,能搞出规律的x轴和y轴就行啦。。。


183632411.jpg



#!/usr/bin/env python
#coding=utf-8
#xiaorui.cc
from flask import Flask,url_for,request,render_template,redirect,abort,escape,session
from werkzeug import secure_filename
import os
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
print __name__
app = Flask(__name__)
app.secret_key = 'hello'
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
@app.route('/')
def index():
    p=os.popen('salt \'*\' grains.item psnum netnum').read()
    p=os.popen('salt \* cmd.run \'netstat -an|wc -l\'').read()
    return '''
<!DOCTYPE html>
<!-- saved from url=(0053)http://www.bootcss.com/examples/marketing-narrow.html -->
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <title>xiaorui.cc</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">
    <!-- Le styles -->
    <link href="http://cdnjs.bootcss.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
    <style type="text/css">
      body {
        padding-top: 20px;
        padding-bottom: 40px;
      }
      /* Custom container */
      .container-narrow {
        margin: 0 auto;
        max-width: 700px;
      }
      .container-narrow > hr {
        margin: 30px 0;
      }
      /* Main marketing message and sign up button */
      .jumbotron {
        margin: 60px 0;
        text-align: center;
      }
      .jumbotron h1 {
        font-size: 72px;
        line-height: 1;
      }
      .jumbotron .btn {
        font-size: 21px;
        padding: 14px 24px;
      }
      /* Supporting marketing content */
      .marketing {
        margin: 60px 0;
      }
      .marketing p + h4 {
        margin-top: 28px;
      }
    </style>
    <link href="http://cdnjs.bootcss.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap-responsive.min.css" rel="stylesheet">
    <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
      <script src="//cdnjs.bootcss.com/ajax/libs/html5shiv/3.6.2/html5shiv.js"></script>
    <![endif]-->
    <!-- Fav and touch icons -->
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="http://www.bootcss.com/assets/ico/apple-touch-icon-144-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://www.bootcss.com/assets/ico/apple-touch-icon-114-precomposed.png">
      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://www.bootcss.com/assets/ico/apple-touch-icon-72-precomposed.png">
                    <link rel="apple-touch-icon-precomposed" href="http://www.bootcss.com/assets/ico/apple-touch-icon-57-precomposed.png">
                                   <link rel="shortcut icon" href="http://www.bootcss.com/assets/ico/favicon.png">
  <script>window["_GOOG_TRANS_EXT_VER"] = "1";</script></head>
  <body>
    <div class="container-narrow">
      <div class="masthead">
        <ul class="nav nav-pills pull-right">
          <li class="active"><a href="http://www.bootcss.com/examples/marketing-narrow.html#">Home</a></li>
          <li><a href="http://www.bootcss.com/examples/marketing-narrow.html#">命令推送</a></li>
          <li><a href="http://www.bootcss.com/examples/marketing-narrow.html#">图标监控</a></li>
        </ul>
        <h3 class="muted">实时监控</h3>
      </div>
      <hr>
      <div class="jumbotron">
        <pre>%s</pre>
        <a class="btn btn-large btn-success" href="http://10.10.10.66:8888">刷新</a>
      </div>
      <hr>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
      <hr>
      <div class="footer">
        <h4>by xiaorui.cc</h4>
      </div>
    </div> <!-- /container -->
    <!-- Le javascript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
</body></html>
'''%p
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
@app.route('/charts.html')
def show_username():
    p=[1,2,3,4,5,6,7,8,9,1,2,3]
    return '''
<!DOCTYPE html>
<!-- saved from url=(0053)http://www.bootcss.com/examples/marketing-narrow.html -->
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <title>xiaorui.cc</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">
    <link href="http://67.xiaorui.cc/bootstrap.min.css" rel="stylesheet">
      <script type="text/javascript"  src="http://code.jquery.com/jquery-1.4.1.min.js"></script>
      <script  type="text/javascript" src="http://67.xiaorui.cc/highcharts.js"></script>
      <script  type="text/javascript" src="http://67.xiaorui.cc/exporting.js"></script>
    <style type="text/css">
      body {
        padding-top: 20px;
        padding-bottom: 40px;
      }
      /* Custom container */
      .container-narrow {
        margin: 0 auto;
        max-width: 700px;
      }
      .container-narrow > hr {
        margin: 30px 0;
      }
      /* Main marketing message and sign up button */
      .jumbotron {
        margin: 60px 0;
        text-align: center;
      }
      .jumbotron h1 {
        font-size: 72px;
        line-height: 1;
      }
      .jumbotron .btn {
        font-size: 21px;
        padding: 14px 24px;
      }
      /* Supporting marketing content */
      .marketing {
        margin: 60px 0;
      }
      .marketing p + h4 {
        margin-top: 28px;
      }
    </style>
<script type="text/javascript">
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
            var chart;
            $(document).ready(function() {
                chart = new Highcharts.Chart({
                    chart: {
                        renderTo: 'container',
                        defaultSeriesType: 'line',
                        marginRight: 130,
                        marginBottom: 25
                    },
                    title: {
                        text: 'netstat 监控',
                        x: -20 //center
                    },
                    subtitle: {
                        text: '让我们看看连接书哈',
                        x: -20
                    },
                    xAxis: {
                        categories: ['1', '2', '3', '4', '5', '6',
                            '7', '8', '9', '10', '11', '12']
                    },
                    yAxis: {
                        title: {
                            text: '连接数'
                        },
                        plotLines: [{
                            value: 0,
                            width: 1,
                            color: '#808080'
                        }]
                    },
                    tooltip: {
                        formatter: function() {
                                return '<b>'+ this.series.name +'</b><br/>'+
                                this.x +': '+ this.y +'°C';
                        },
                    },
                    legend: {
                        layout: 'vertical',
                        align: 'right',
                        verticalAlign: 'top',
                        x: -10,
                        y: 100,
                        borderWidth: 0
                    },
                    series: [{
                        name: '66.ruifengyun.cc',
                        data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
                    }, {
                        name: '67.ruifengyun.cc',
                        data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
                    }, {
                        name: 'ceshi',
                        data: %s
                    }]
                });
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
            });
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
        </script>
    <!-- Fav and touch icons -->
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="http://www.bootcss.com/assets/ico/apple-touch-icon-144-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://www.bootcss.com/assets/ico/apple-touch-icon-114-precomposed.png">
      <link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://www.bootcss.com/assets/ico/apple-touch-icon-72-precomposed.png">
                    <link rel="apple-touch-icon-precomposed" href="http://www.bootcss.com/assets/ico/apple-touch-icon-57-precomposed.png">
                                   <link rel="shortcut icon" href="http://www.bootcss.com/assets/ico/favicon.png">
  <script>window["_GOOG_TRANS_EXT_VER"] = "1";</script></head>
  <body>
    <div class="container-narrow">
      <div class="masthead">
        <ul class="nav nav-pills pull-right">
          <li><a href="http://66.xiaorui.cc:8888">Home</a></li>
          <li><a href="http://66.xiaorui.cc:8888/pushcmd">命令推送</a></li>
          <li class="active"><a href="http://66.xiaorui.cc:8888/charts.html#">图表监控</a></li>
        </ul>
        <h3 class="muted">图表监控</h3>
      </div>
      <hr>
      <div class="jumbotron">
        <div id="container" style="width: 800px; height: 400px; margin: 0 auto"></div>
        <a class="btn btn-large btn-success" href="http://10.10.10.66:8888">刷新</a>
      </div>
      <hr>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
      <hr>
      <div class="footer">
        <h4>by xiaorui.cc</h4>
      </div>
    </div> <!-- /container -->
    <!-- Le javascript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
</body></html>
'''%p
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
@app.route('/post/<int:post_id>')
def show_post(post_id):
    return 'post_id:%d' % post_id
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
@app.route('/index/')
def test_session():
    if 'username' in session:
        return 'logged in as %s' % escape(session['username'])
    return redirect(url_for('login'))
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
@app.route('/login/',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('test_session'))
    else:
        return
'''
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
<form action="/login/" method="post">
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
<input type=text name=username>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
<input type=submit value=login>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
</form>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
'''
if __name__ == "__main__":
    app.run(host="10.10.10.66",port=8888,debug=True)



还有一种展现方式,就是油表

031054485.jpg

这个数据很方面的传到页面上去的。

通过后端改变value的值就行啦~

<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jquery.knob.js"></script>
<input type="text" class="dial" data-min="-40" data-max="70">
要是不显示的话,再加上这段语句
$(".dial").knob({
'min':-40
,'max':70
})




这里说下 saltstack  grains 的采集~ 例子如下

224312937.jpg

我要可以取出 name和lang的值。    [xiaorui.cc]

225101471.jpg


采集全部信息

salt '*' grains.items


224827258.jpg

224827399.jpg

224827618.jpg

我们通过items查看 很多的系统信息。

原文地址:http://rfyiamcool.blog.51cto.com/1030776/1266437

实时采集的话,就要取消master对grains的缓存

231957703.jpg


更新数据缓存,结果

232236944.jpg


貌似刷新有点问题~   应该是他的一个bug吧~


经过 saltstack 专业人士  大牛  大神 帅锅 沈灿 的一段时间折腾得知,grains信息是每次客户端启动后 就确定了的   除非你每次采集钱都 重启 minion 或者 重新同步下 grains。

原文地址:http://rfyiamcool.blog.51cto.com/1030776/1266437

页面上又增加了几个功能,其实睡觉前写完了,但是有些bug

  等都调试好了后,在给大家贴下实现代码。

多选控件                          【xiaorui.cc】

034805221.jpg

模块上传

035004528.jpg


编辑各种              【xiaorui.cc】

035024981.jpg


连载中~

找个时间更新下~