前言:自己的挖的坑还得填,此篇为完结篇。
环境的搭建参考第一篇 从无到有写一个运维APP(一),至于第二篇就跳过吧,写个 APP 没那么复杂。
由于自己现在无业游民,所以没有什么现成的环境,环境就随便找个公网的。再者当下的完成度应该算不上一个完整的 APP,但是作为参考,依瓢画葫芦绝对足够了,如果等完整产品,可能得等一段时间了,下面的是该项目的地址。
项目地址: https://github.com/youerning/MyApp(star一下呗)
效果图如下
wKiom1lHrUHyQM8MAAAY4_S_xnE795.png-wh_50
wKiom1lHrUGQ3u60AAAcoO04O6I984.png-wh_50
wKioL1lHrUKxhk1RAAA8JhhMyTY466.png-wh_50
wKioL1lHrUPxjFXHAAAowsdCZXo571.png-wh_50
文章目录:
1. 准备工作
2. 代理
3. 页面框架
4. 获取数据
5. 绘图
6. 自问自答
页面逻辑简要说明:
1. 一共三个 tab,分别为 home,es,zabbix。
2. home 页面有 es,zabbix 的性能指标。
3. es页面可以图形展示搜索的数据。
4. zabbix页面可以图形展示搜索的数据(没有环境所以留空)。
(一)
1. 环境搭建参考:第一篇 http://youerning.blog.51cto.com/10513771/1735450
2. es 服务器
因为没有现成的 es 环境再者自己搭建还得往里面填数据,这太难过了,所以通过 shodan 找一个暴露在公网的 es 服务器。
wKioL1lHrh3C9YW4AAJyUm4btbE005.png-wh_50
3. 创建一个 APP
ionic start myops blank
4. sublime 打开该项目
wKiom1lHrj2Q3I-tAAEd7A-HCFs180.png-wh_50
(二)
1. 搭建代理
虽说 app 里面似乎没有跨域的限制,但是自己在调试的时候还是可能被这个跨域弄得焦头烂额的。
所以可以通过 flask 简单的写一个代理页面,代码如下,如你所见,我把这个暴露在公网的 es 服务器的 IP 写出来,的确有点不道德(大家不要搞破坏呀~数据量这么丰富的还是比较难找的呀)。
from flask import Flask
from flask import Response, request, abort
import urlparse
import requests
import json
app = Flask(__name__)
esUrl = "http://176.31.137.145:9200/"
@app.route("/<app>", methods=["GET","POST"])
def index(app):
params = "?format=json&pretty"
data = {}
error = ""
req = getattr(requests, request.method.lower())
if app == "es":
arg = request.args["api"]
if "search" in arg:
params = params + "&size=0"
url = urlparse.urljoin(esUrl, arg + params)
# print url
page = req(url) if request.method == "GET" else req(url, request.data)
if page.ok:
try:
ret = page.json()
except Exception as e:
ret = page.content
error = str(e)
else:
ret = "The url:%s request faild" % url
error = "request faild"
elif app == "zab":
ret = [{"status":"ok"}]
else:
ret = ""
error = "incorrect url"
data["data"] = ret
data["error"] = error
resp = Response(json.dumps(data))
if error:
abort(500)
resp.headers["Content-Type"] = "application/json; charset=UTF-8"
resp.headers["access-control-allow-origin"] = "*"
return resp
if __name__ == "__main__":
app.run(port=80,debug=True,host="0.0.0.0")
这个页面的效果如下。
wKioL1lHr2PxD1WrAAAw8U7_DUM679.png-wh_50
(三)
1. 页面框架
就如上面的效果图,我们应该需要三个 tab,然后一个 es 性能的模板页面,一个详情模板页面。
所以目录结构大体如下。
wKiom1lHr5LBpRleAAAqtEqfpRw519.png-wh_50
总而言之,我们需要五个模板,所以在 www 目录下创建了一个 tpls 的目录用于放置我们的模板文件。
完整源代码,可以访问我的 GitHub。
2. 页面框架编写。
首先在入口页撰写总体布局:
<body ng-app="myops">
<ion-pane>
<ion-nav-bar class="bar-positive">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<ion-tabs class="tabs-icon-top">
<ion-tab title="Home" icon="ion-home" href="#/home">
<ion-nav-view name="tab-home"></ion-nav-view>
</ion-tab>
<ion-tab title="es" icon="ion-ionic" href="#/es">
<ion-nav-view name="tab-es"></ion-nav-view>
</ion-tab>
<ion-tab title="zabbix" icon="ion-ionic" href="#/zabbix">
<ion-nav-view name="tab-zabbix"></ion-nav-view>
</ion-tab>
</ion-tabs>
</ion-pane>
</body>
创建视图文件,大致结构如下,home.html,es.html.zabbix.html等
<ion-view view-title="{YOUR TITLE}">
<ion-content>
{YOUR CONTENT}
</ion-content>
</ion-view>
编写路由逻辑。
app.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$ionicConfigProvider.tabs.position('bottom');
$stateProvider
.state("home", {
url:"/home",
views:{
"tab-home":{
controller:"homeCtrl",
templateUrl: "tpls/home.html"
}
}
});
$stateProvider
.state("detail", {
url:"/detail/:name",
views:{
"tab-es":{
controller:"detailCtrl",
templateUrl: "tpls/detail.html"
}
}
});
$stateProvider
.state("perf", {
url:"/perf/:name",
views:{
"tab-home":{
controller:"perfCtrl",
templateUrl: "tpls/perf.html"
}
}
});
$stateProvider
.state("es", {
url:"/es",
views:{
"tab-es":{
controller:"esCtrl",
templateUrl: "tpls/es.html"
}
}
});
$stateProvider
.state("zabbix", {
url:"/zabbix",
views:{
"tab-zabbix":{
controller:"zabbixCtrl",
templateUrl: "tpls/zabbix.html"
}
}
});
$urlRouterProvider.otherwise("/home");
})
(四)
1. 获取数据
这里我们通过 angularjs 内置的 $http 访问相应的 api,大致如下。
$http.get(esUrl, {params:{api: "_cat/health"}}).then(function(resp){
$scope.data.status = resp.data.data[0].status;
}, function(resp) {
$scope.data.status = "something wrong";
});
本来性能指标应该是时间序列的监控数据,但是由于没有环境,这里就简单的列出当前指标值。
perf.html 内容如下。
<ion-view view-title="Performance for {{name | uppercase}}">
<ion-content>
<ion-list class="cards">
<ion-item>how many nodes: `data`.`nodes`</ion-item>
<ion-item>how many shards: `data`.`shards`</ion-item>
<ion-item>status:`data`.`status`</ion-item>
<ion-item>how many indices: `data`.`indices`</ion-item>
<ion-item>how many documnet:`data`.`counts`</ion-item>
</ion-list>
</ion-content>
</ion-view>
(五)
1. 绘图
这里绘图使用 chart.js
2. 安装 chart.js
在项目目录下执行下面命令
bower install angular-chart.js
3. 在 index.html 引入 js 文件
<script src="lib/chart.js/dist/Chart.min.js"></script>
<script src="lib/angular-chart.js/dist/angular-chart.min.js"></script>
4. 检索 es 中我们感兴趣的字段
通过检索 mapping 效果如下
wKioL1lHsUmCOGUEAABnHI9ssvo802.png-wh_50
个人而言,感觉可玩的是 clientip,agent,response
我们利用 es 的 api 统计以下上面的字段吧。
因为聚合需要 post 方法,所以这里使用 postman。
效果如下
wKioL1lHsW-iDnh_AABdu_lOvxE185.png-wh_50
wKiom1lHsXSQucDaAAC7IoZDneo662.png-wh_50
5. 通过 $http 获取数据
$http.post(esUrl, setData($scope.name), {params:{api:"_search"}}).then(function(resp) {
var ret = resp.data.data.aggregations.top_tags.buckets;
console.log(ret);
$scope.labels = [];
$scope.series = [$scope.name];
$scope.data = [];
for (var i=0;i<ret.length;i++){
$scope.labels.push(ret[i]["key"]);
$scope.data.push(ret[i]["doc_count"]);
}
},function(resp) {
// console.log(resp.config);
})
6. 模板内容如下
<ion-view view-title="Detail for `name`">
<ion-content>
<ion-list >
<ion-item>
<canvas id="bar" class="chart chart-bar"
chart-data="data" chart-labels="labels"> chart-series="series"
</canvas>
</ion-item>
<ion-item ng-repeat="label in labels">
<h2>`label`</h2>
<p>{{data[$index]}}</p>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
7. 绘图
wKiom1lHscbSYjA1AAA8JhhMyTY753.png-wh_50
(六)
自问自答
Q:为毛不用最新的 ionic
A:暂时没有看 typescript 的看法
Q:能画其他图么?
A:参考 http://jtblin.github.io/angular-chart.js/
Q:为毛没有获取一下 zabbix 的数据
A:没环境,不想搭
不足
1. 有一些重复的代码
2. 不够足够好看
3. 没有将 url 的控制权交给 APP
如果觉得不错,并有所收获,请我喝杯茶呗
wKioL1lU4MXwELckAADg-gB3Tsc583.jpg-wh_50wKiom1lU4Mqg8rxIAADzypnX0FU518.jpg-wh_50
©著作权归作者所有:来自51CTO博客作者youerning的原创作品,如需转载,请注明出处,否则将追究法律责任