授之以渔-运维平台发布模块二(Jenkins篇)

接上篇《授之以渔-运维平台发布模块一(Jenkins篇)》,今天介绍下结合着Saltstack的MasterEven,用来做发布系统的结果监控。

#一、Event介绍
SaltStack 0.10版本中, 新增了Event系统, 官方在 Release Notes 对其描述如下:

The Salt Master now comes equipped with a new event system. This event system has replaced some of the back end of the Salt client and offers the beginning of a system which will make plugging external applications into Salt. The event system relies on a local ZeroMQ publish socket and other processes can connect to this socket and listen for events. The new events can be easily managed via Salt’s event library.
同时官方也在 Salt Event系统 页面中提供了监听event的例子程序, 基于其进行下Event系统学习.
我们所需要的就是监听event,然后把结果存储到Mysql,Redis之类,以便于我们后续进行处理。

#二、Event代码:

import salt.utils.event
import redis

def redis_conect_db6():
    try:
        r = redis.StrictRedis('172.18.11.126', 6379, 6)
    except:
        pass
    return r

event = salt.utils.event.MasterEvent('/var/run/salt/master')
for data in event.iter_events(full=True):
	r = redis_conect_db6()
	ret = data['data']
	if 'salt/job/' in data['tag']:
		if ret.has_key("id") and ret.has_key("return") and ret.has_key("fun") :
			if ret['fun'] != 'mine.update':
				if len(ret['fun_args']) >0 and 'wwwlogs' not in ret['fun_args'][0]:
					print data
					print "====================================================="
					if ret['fun'] == 'pkg.get_repo' and ret['return'] != {}:
						r.set('%s:%s-%s'%(ret['return']['name'],ret['id'],ret['fun']), ret)
					elif ret['fun'] == 'pkg.upgrade_available' :
						r.set('%s:%s-%s'%(ret['fun_args'][0],ret['id'],ret['fun']), ret)
					elif ret['fun'] == 'pkg.install' and ret['return'] != {}:
						r.set('%s:%s-%s'%(ret['fun_args'][0],ret['id'],ret['fun']), ret)

这段event脚本的大体实现了过滤一些非必要信息,把fun中包含pkg.get_repo(验证Yum是否存在),pkg.upgrade_available(验证Yum是否更新),pkg.install(安装)存储到Redis中。然后我只需要去Redis中取出数据,并通过highcharts.js汇出图即可。

#三、后端处理Redis数据绘图代码:

@login_required
@my_permissionVerify
def release_status(request):
    if 'id' in request.GET:
        svn_name = request.GET['id']
        Svn_name = Svn.objects.get(svn_name = svn_name)
        r = redis_conect_db6()
        svn_list = []
        nodes = [{"area":0,"status":2,"no":0,"parent":[],"label":"%s" % str(Svn_name.svn_name)}]
        for svn_host in (Svn_name.svn_hosts).split(','):
            area_dict1 = {}
            area_dict2 = {}
            area_dict3 = {}
            svn_list_dict = {}
            area_dict1["area"] = 1
            area_dict1["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
            area_dict1["label"] = "%s" % str(svn_host)
            area_dict1["parent"] = [{"parea":0,"pno":0}]
            area_dict1["status"] = 0
            nodes.append(area_dict1)
            area_dict2["area"] = 2
            area_dict2["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
            area_dict2["label"] = "%s" % str(svn_host)
            area_dict2["parent"] = [{"parea":1,"pno":int(area_dict2["no"])}]
            area_dict2["status"] = 0
            nodes.append(area_dict2)
            area_dict3["area"] = 3
            area_dict3["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
            area_dict3["label"] = "%s" % str(svn_host)
            area_dict3["parent"] = [{"parea":2,"pno":int(area_dict3["no"])}]
            area_dict3["status"] = 0
            nodes.append(area_dict3)
            """排除同一个主机,多个项目"""
            try:
                if str(Svn_name) in r.get('%s:%s-%s' % (svn_name, svn_host,'pkg.get_repo')):
                    nodes[0] = {"area":0,"status":3,"no":0,"parent":[],"label":"%s" % str(Svn_name.svn_name)}

                    if nodes[0]['status'] == 3:
                        area_dict1["status"] = 2
                        try:
                            if json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.get_repo')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['success'] == "True":
                                area_dict1["status"] = 3
                            else:
                                area_dict1["status"] = 1
                        except:
                            area_dict1["status"] = 0
                        area_dict1["area"] = 1
                        area_dict1["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
                        area_dict1["label"] = "%s" % str(svn_host)
                        area_dict1["parent"] = [{"parea":0,"pno":0}]
                        svn_list_dict['host'] = svn_host
                        svn_list_dict['name'] = Svn_name
                        svn_list_dict["release_svn"] = Svn_name.svn_no

                        """添加检测YUM源存在时间"""
                        try:
                            svn_list_dict['get_repo_time'] = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.get_repo')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['_stamp_localtime']
                        except:
                            svn_list_dict['get_repo_time'] = ''
                        nodes.append(area_dict1)
                        print 'nodes,',nodes[1]['status']
                    else:
                        area_dict1["status"] = 0

                    if nodes[1]['status'] == 3:
                        area_dict2["status"] = 2
                        try:
                            if json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.upgrade_available')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['success'] == "True":
                                area_dict2["status"] = 3
                            else:
                                area_dict2["status"] = 1
                        except:
                            area_dict2["status"] = 2
                        area_dict2["area"] = 2
                        area_dict2["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
                        area_dict2["label"] = "%s" % str(svn_host)
                        area_dict2["parent"] = [{"parea":1,"pno":int(area_dict2["no"])}]

                        """添加RPM检测更新时间"""
                        try:
                            svn_list_dict['upgrade_available'] = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.upgrade_available')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['_stamp_localtime']
                        except:
                            svn_list_dict['upgrade_available'] = ''
                        nodes.append(area_dict2)
                    else:
                        area_dict2["status"] = 0

                    if nodes[2]['status']  == 3:
                        area_dict3["status"] = 2
                        try:
                            if json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['success'] == "True":
                                if json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['return']['%s'% svn_name]['old'] != '':
                                    release_old = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['return']['%s'% svn_name]['old'].split('-')[0]
                                else:
                                    release_old = 0
                                try:
                                    release_new = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['return']['%s'% svn_name]['new'].split('-')[0]
                                except:
                                    release_new = ''
                                if (int(release_old)+1 == int(release_new)) and (int(release_new) == int(Svn_name.svn_no)):
                                    area_dict3["status"] = 3
                                elif int(release_old) == int(release_new):
                                    area_dict3["status"] = 2
                                else:
                                    area_dict3["status"] = 1
                            else:
                                area_dict3["status"] = 1
                        except:
                            area_dict3["status"] = 2
                        area_dict3["area"] = 3
                        area_dict3["no"] = (Svn_name.svn_hosts).split(',').index(svn_host)
                        area_dict3["label"] = "%s" % str(svn_host)
                        area_dict3["parent"] = [{"parea":2,"pno":int(area_dict3["no"])}]
                        """添加RPM安装时间"""
                        try:
                            svn_list_dict['install'] = json.loads(r.get('%s:%s-%s' % (svn_name, svn_host, 'pkg.install')).replace("'", "\"").replace('True','"True"').replace('False','"False"'))['_stamp_localtime']

                            svn_list_dict["release_new"] = release_new
                        except:
                            svn_list_dict['install'] = ''

                        nodes.append(area_dict3)
                    else:
                        area_dict3["status"] = 0
                else:
                    pass
                svn_list.append(svn_list_dict)
            except Exception as err:
                print 'Release_status_err:',err
        return render_to_response('myrelease/release_status.html',{'svn_list':svn_list,'nodes':nodes},context_instance=RequestContext(request))
    else:
        return render_to_response('myrelease/release_status.html',context_instance=RequestContext(request))

这段代码大体实现了通过判断pkg.get_repo(验证Yum是否存在),pkg.upgrade_available(验证Yum是否更新),pkg.install(安装)返回的状态,来输出不同的status,前端会根据不同的status,绘制不同的颜色。

#四、效果图:

Paste_Image.png

#五、前端代码:

<script type="text/javascript">
    $(function () {
        var chart = new Highcharts.Chart({
            chart: {
                renderTo: 'container_drawing',
                events: {
                    load: drawing
                }
            },
            title: {
                text: ''
            }
        });
    });
    /* 画图自定义函数 */
    function drawing(){
        // Draw the flow chart
        var ren = this.renderer;
        var rightArrow = ['M', 0, 0, 'L', 100, 0, 'L', 95, 5, 'M', 100, 0, 'L', 95, -5];
        var colors = ['#2570a1','#d71345','#decb00','#1d953f'];//四种状态对应的颜色:未启动,告警,正在运行,完成

        // 分割线1
        ren.path(['M', 270, 40, 'L', 270, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();
        // 分割线2
        ren.path(['M', 520, 40, 'L', 520, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();
        // 分割线3
        ren.path(['M', 770, 40, 'L', 770, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();
        // 分割线4
//        ren.path(['M', 1020, 40, 'L', 1020, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();
        // 分割线5
//        ren.path(['M', 1270, 40, 'L', 1270, 600]).attr({'stroke-width': 3,stroke: 'silver',dashstyle: 'dash'}).add();




        // 区域标题

        ren.label('包构建', 110,50).css({fontWeight: 'bold'}).add();
        ren.label('验证源', 370,50).css({fontWeight: 'bold'}).add();
        ren.label('验证包更新', 610, 50).css({fontWeight: 'bold'}).add();
//        ren.label('前置命令', 880, 50).css({fontWeight: 'bold'}).add();
        ren.label('项目包安装', 880, 50).css({fontWeight: 'bold'}).add();
//        ren.label('后置命令', 1380, 50).css({fontWeight: 'bold'}).add();

        // 遍历生成图形
        /**
            area:区域编码,值为:0,1,2,null.
            no:节点序号,值为:0,1,...,N,null.
            label:节点内容.
            status:节点状态值为:0为未执行,1为错误,2为执行中,3为执行完毕
            parea:父节点区域编码,值为:0,1,2,null.
            pno:父节点序号,值为:0,1,...,N,null.
        */
//        var nodes = [{"area":5,"status":2,"no":0,"parent":[{"parea":4,"pno":0}],"label":"md25-qnzs-app-13.youth.cn"},{"area":4,"status":3,"no":0,"parent":[{"parea":3,"pno":0}],"label":"md25-qnzs-app-13.youth.cn"},{"area":3,"status":3,"no":0,"parent":[{"parea":2,"pno":0}],"label":"md25-qnzs-app-13.youth.cn"},{"area":2,"status":3,"no":0,"parent":[{"parea":1,"pno":0},{"parea":1,"pno":1}],"label":"md25-qnzs-app-13.youth.cn"},{"area":1,"status":1,"no":0,"parent":[{"parea":0,"pno":0},{"parea":0,"pno":1},{"parea":0,"pno":3}],"label":"md25-qnzs-app-13.youth.cn"},{"area":1,"status":0,"no":1,"parent":[{"parea":0,"pno":1},{"parea":0,"pno":2}],"label":"md25-qnzs-app-13.youth.cn"},{"area":0,"status":0,"no":0,"parent":[],"label":"md25-qnzs-app-13.youth.cn"},{"area":0,"status":1,"no":1,"parent":[],"label":"md25-qnzs-app-13.youth.cn"},{"area":0,"status":2,"no":2,"parent":[],"label":"md25-qnzs-app-13.youth.cn"},{"area":0,"status":1,"no":3,"parent":[],"label":"md25-qnzs-app-13.youth.cn"}];
        var nodes = {% autoescape off %}{{ nodes}}{% endautoescape %}
        for(var i=0;i<nodes.length;i++){
            var node = nodes[i];
            ren.label(node.label, 30+node.area*250, 80+node.no*50).attr({fill: colors[node.status],stroke: '#f2eada','stroke-width': 2,padding: 5,r: 9,width:220,height:20}).css({color: 'white',fontSize:'xx-small',textAlign:'center',fontWeight: 'bold'}).add().shadow(true);
            for(var j=0;j<node.parent.length;j++){
                var parent = node.parent[j];
               ren.path(['M', 30+node.area*250, 75+node.no*50+20, 'L', 2+parent.parea*250+250+10, 75+parent.pno*50+20]).attr({'stroke-width': 2,stroke: '#4169E1'}).translate(0, 0).add();//
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值