博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
授之以渔-运维平台应用模块一(应用树篇)
阅读量:6608 次
发布时间:2019-06-24

本文共 14131 字,大约阅读时间需要 47 分钟。

写在片头:干的是运维工作,爱好动手。纯属个人项目,身兼业务需求人员,产品经理,前端,后端,测试于一体,代码层面会有逻辑问题,请各位看官见谅,下文只是记录我一个10手码农在前端踩过的坑和一些思路。

###应用树: 为了方便管理以业务为单位的服务集群,利用树形结构建立起了一种服务组织关系,方便运维日常管理。先上一张效果图:

授之以渔-运维平台应用模块一(应用树篇)

#一、 Jstree

看过XX公司的运维平台的应用树后,从此不能自拔,励志也要写出一样效果的东东。采用的jsTree,是基于javascript的一个跨浏览器树控件树行,功能强大,最重要的是免费,
左侧的树列表的生成因为会用到mysql的group by,所以采用了redis存储,需要的时候才更新服务树,减少对数据库的压力,项目用到了根据选择树节点点击事件功能。
既点击项目名称的红×××标时,会加载整个项目涉及到的服务器,效果图:
image.png
点击项目下单个主机时,会加载这个服务器的应用情况,效果图:
image.png

代码如下:

("changed.jstree", function (e, data) {                var items = data.node.text;                var icon = data.node.icon;                if (icon == "fa fa-building-o font-blue"){                    document.getElementById("group1").style.display="none";                    document.getElementById("group2").style.display="block";                    $.ajax({                        type: "GET",                        url: "../cmdb_app_info_ajax/?ip="+items,                        dataType:'json',                        async: false,                        beforeSend:function(){                            Metronic.blockUI({animate: true});                        },                        complete: function() {                            Metronic.unblockUI();                        },                        success: function(data){                           var  sOut= '';                                sOut += ''                                sOut += '' + data['设备PHP版本号:'] + '';                                sOut += '' + data['设备PHP路径:'] + '';                                sOut += '' + data['设备PHP端口号:'] + '';                                sOut += ''                                sOut += 'TOMCAT版本号';                                sOut += 'TOMCAT路径';                                sOut += 'TOMCAT端口号';                                sOut += ''                                sOut += '' + data['设备TOMCAT版本号:'] + '';                                sOut += '' + data['设备TOMCAT路径:'] + '';                                sOut += '' + data['设备TOMCAT端口号:'] + '';                                sOut += ''                                sOut += 'NGINX版本号';                                sOut += 'NGINX路径';                                sOut += 'NGINX端口号';                                sOut += ''                                sOut += '' + data['设备NGINX版本号:'] + '';                                sOut += '' + data['设备NGINX路径:'] + '';                                sOut += '' + data['设备NGINX端口号:'] + '';                                sOut += ''                                sOut += 'MYSQL版本号';                                sOut += 'MYSQL路径';                                sOut += 'MYSQL端口号';                                sOut += 'MYSQL数据库';                                sOut += ''                                sOut += '' + data['设备MYSQL版本号:'] + '';                                sOut += '' + data['设备MYSQL路径:'] + '';                                sOut += '' + data['设备MYSQL端口号:'] + '';                                sOut += '' + data['设备MYSQL数据库:'] + '';                                sOut += ''                                sOut += '定时任务';                                sOut += ''                                sOut += '' + data['设备定时任务:'] + '';                                sOut += ''                            $("#cmdb_app_info_get").html(sOut);                            },                        error: function (data) {                            toastr.error('没有数据可以加载')                        }                    });                }else if (icon == "fa fa-folder icon-state-warning icon-lg"){                    document.getElementById("group1").style.display="block";                    document.getElementById("group2").style.display="none";                    $.ajax({                        type: "GET",                        url: "../cmdb_subtitle_info_ajax/?subtitle="+items,                        dataType:'json',                        async: false,                        beforeSend:function(){                            Metronic.blockUI({animate: true});                        },                        complete: function() {                            Metronic.unblockUI();                        },                        success: function(data){                            if ($('#product_tree').hasClass('dataTable')) {                                console.log('重新加载datatable,准备初始化................')                                $('#product_tree').dataTable().fnClearTable(false) //清空一下table                                $('#product_tree').dataTable().fnDestroy();//还原初始化datatable                            }                            $("#cmdb_subtitle_info_get").html("");                            $.each(data,function() {                            var  sOut= '';                                sOut += ''                                sOut += ''                                sOut += '' + '' + this['fields']['unit_title'] + '' + '';                                sOut += '' + this['fields']['unit_subtitle'] + '';                                sOut += '' + this['fields']['unit_ip'] + '';                                sOut += '' + this['fields']['unit_use_type'] + '';                                                            sOut += '';                                sOut += ''                                $("#cmdb_subtitle_info_get").append(sOut);                            });                        },                        error: function (data) {                            toastr.error('没有数据可以加载')                        }                    });                }                $(document).ready(function(){                    eyeClick();                    TableManaged.init() //初始化datatables                })            }

捡一些重要的说:

var items = data.node.text;  //获取图标名称var icon = data.node.icon;  //获取图标

我是通过判断图标的样式来获取用户点击的是哪里,没办法,谁叫咱是10手码农。同时有group1和gourp2两个tables,选择哪个图标就弹出哪个tables,隐藏另外的,在通过ajax后台获取数据,利用each循环获得的结果,构建出一个tr的内容,最后在添加到tables里,以此实现“山寨版”的数据加载。

####这里踩过的坑:
因为我要先加载完数据,然后才是初始化datatables表格。当点击到别的业务图标时,又要经历一次加载数据,然后初始化表格。结果datatables报错了....cannot reinitialise datatable,大概意思就是datatables不能重复初始化。
最后只能通过判断加载后的tables是否被加载后,如果加载过,先销毁,在初始化。

if ($('#product_tree').hasClass('dataTable')) {    console.log('重新加载datatable,准备初始化................')    $('#product_tree').dataTable().fnClearTable(false) //清空一下table    $('#product_tree').dataTable().fnDestroy();//还原初始化datatable}

#二、 Datatable

右边就是数据展示采用datatables,可以将任何HTML表格添加高级的交互功能,这里用到了checkbox的单选和多选。
datatables代码如下:

var TableManaged = function () {    var initTable2 = function () {        var table = $('#product_tree');        table.dataTable({            "bDestroy": true,            "language": {                "aria": {                    "sortAscending": ": activate to sort column ascending",                    "sortDescending": ": activate to sort column descending"                },                "emptyTable": "未有相关数据",                "info": "当前显示 _START_ 到 _END_ 条,共 _TOTAL_ 条记录。",                "infoEmpty": "当前显示0到0条,共0条记录",                "infoFiltered": "(数据库中共为 _MAX_ 条记录)",                "lengthMenu": "显示 _MENU_ 记录",                "search": "模糊查询:",                "zeroRecords": "对不起,查询不到任何相关数据",                "oPaginate": {                    "sFirst": "首页",                    "sPrevious": " 上一页 ",                    "sNext": " 下一页 ",                    "sLast": " 尾页 "                }            },            "bStateSave": true, // save datatable state(pagination, sort, etc) in cookie.            "lengthMenu": [                [5, 15, 20, -1],                [5, 15, 20, "All"] // change per page values here            ],            // set the initial value            "pageLength": 5,            "columnDefs": [{  // set default column settings                'orderable': false,                'targets': [0]            }, {                "searchable": false,                "targets": [0]            }],            "order": [                [1, "asc"]            ] // set first column as a default sort by asc        });        var tableWrapper = jQuery('#product_tree_wrapper');        var host_list = [];        var release_build_job = '';        //全选        table.find('.group-checkable').change(function () {            var set = jQuery(this).attr("data-set");            var checked = jQuery(this).is(":checked");            host_list.length = 0;            jQuery(set).each(function () {                if (checked) {                    $(this).attr("checked", true);                    var hosts = $(this).parent().parent().find('td').eq(1).attr("id");                    host_list.push(hosts);                    document.getElementById("group3").style.display="block";                } else {                    $(this).attr("checked", false);                    host_list.length = 0;                    document.getElementById("group3").style.display="none";                }            });            jQuery.uniform.update(set);        });        //单选        table.on('change', 'tbody tr .checkboxes', function () {            var hosts = $(this).parent().parent().find('td').eq(1).attr("id");            var checked = jQuery(this).is(":checked");            if (checked) {                $(this).attr("checked", true);                host_list.push(hosts);                if (host_list.length > 1) {                    document.getElementById("group3").style.display="block";                }else {                    document.getElementById("group3").style.display="none";                }            } else {                $(this).attr("checked", false);                host_list.pop(hosts);                if (host_list.length > 1) {                    document.getElementById("group3").style.display="block";                }else {                    document.getElementById("group3").style.display="none";                }            }        });        tableWrapper.find('.dataTables_length select').select2(); // initialize select2 dropdown    return {        //main function to initiate the module        init: function () {            if (!jQuery().dataTable) {                return;            }            initTable2();        }    };}();

捡一些重要的说:

if (host_list.length > 1) {    document.getElementById("group3").style.display="block";}else {    document.getElementById("group3").style.display="none";}

判断了checkbox选择的数量,大于1个的话,弹出gourp3(一个批量绘图按钮),效果图如下:

image.png

#三、 Multiselect

接上文,这里平台是结合了openfalcon做的监控,点击上文的监控指标项按钮,会弹出一个multiselect层,用过openfalcon的都知道,监控指标多是他的特色之一,所以在选型的时候第一个就想到得需要一个带filter功能的select控件,效果图如下:
image.png
代码如下:

$('#get_hostlist_counter_select').multiselect({                    buttonWidth: '500px',//按钮宽度                    nonSelectedText: '---- 请选择监控指标 ----',                    nSelectedText: '个被选中',                    enableCaseInsensitiveFiltering: true,//不区分大小写                    filterPlaceholder: '模糊查询',                    enableFiltering: true,                    onDropdownShow: function(event) {                        get_hostlist_counter()                    },                    onChange: function (option, checked, select) {                        var selectedOptions = $('#get_hostlist_counter_select option:selected');                        if (selectedOptions.length >= 6) {                            // 禁用选项                            toastr.error('监控指标最多同时选取6个')                            var nonSelectedOptions = $('#get_hostlist_counter_select option').filter(function() {                            return !$(this).is(':selected');                            });                            nonSelectedOptions.each(function() {                            var input = $('input[value="' + $(this).val() + '"]');                            input.prop('disabled', true);                            input.parent('li').addClass('disabled');                            });                        }                        else {                            // 启动选项                            $('#get_hostlist_counter_select option').each(function() {                            var input = $('input[value="' + $(this).val() + '"]');                            input.prop('disabled', false);                            input.parent('li').addClass('disabled');                            });                        }                    }            });

捡重要的说:

用到了multiselectonDropdownShowonChange两个回调函数,onDropdownShow可以理解成就是点击菜单下拉事件,触发了get_hostlist_counter()通过ajax取数据填充options,代码如下:

function get_hostlist_counter(){                var options_list = []                var obj2 = new Object();                var jsonData ={                    'unit_title': host_list.join(','),                };                $("#get_hostlist_counter_select").empty();                $.ajax({                    async: false,                    type: "POST",                    url : "../openfalcon_get_endpoint_counter_ajax/",                    data: jsonData,                    cache: false,                    dataType: "json",                    beforeSend:function(){                        Metronic.blockUI({animate: true});                    },                    complete: function() {                        Metronic.unblockUI();                    },                    success: function(obj) {                        if (obj['counter'] == ''){                            toastr.error('获取监控指标为空或者异常')                        }else{                            for (var id in obj['counter']){                                    obj2 = {                                          label : obj['counter'][id],                                          value : obj['counter'][id],                                      };                                options_list.push(obj2)                                }                            $('#get_hostlist_counter_select').multiselect('dataprovider', options_list);                            }                            }                        });            }

onChange可以理解成点击事件,监控指标这块还是怕传多了,压垮了openfalcongraph的,所以限制最多传6个,超过的话会禁用所有选项。

#四、 绘图
最后就是一些绘图了,结合着openfalcon的API做的,下篇文章再议,效果图:
image.png

转载于:https://blog.51cto.com/qdream/2405083

你可能感兴趣的文章
python3基础——函数(2)
查看>>
TOKEN设计
查看>>
yum更换国内源、yum下载rpm包 、源码包安装
查看>>
常用Oracle旳SQL函数
查看>>
BCH或将在日本迎来新的上涨点
查看>>
从HelloWorld看Knative Serving代码实现
查看>>
linux`操作文本的三大利器
查看>>
【CentOS 7笔记39】,监控系统状态1#
查看>>
LAMP架构PHP模块支持与虚拟主机配置
查看>>
一块GPU就能训练语义分割网络,百度PaddlePaddle是如何优化的?
查看>>
详解netty原理分析
查看>>
ubuntu sublime text中文输入法和乱码问题
查看>>
病人spark处理-元组和case class 对数据进行结构化
查看>>
CSS布局1:用三个div实现左右两列固定,中间自适应
查看>>
Nginx功能配置(反向代理、SSL)
查看>>
linux杂项
查看>>
数组的 基本操作 【增删查改】
查看>>
IT兄弟连 JavaWeb教程 AJAX常见问题
查看>>
感谢,终于有人把云计算、大数据和人工智能讲明白了!
查看>>
FtpUtil
查看>>