You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
283 lines
17 KiB
283 lines
17 KiB
/*
|
|
* The PMPinnedDetailView is the controller for a pinned entities in the proactive monitoring visualization
|
|
* Most notably it will control the creation of the required searches and sub views for an entity
|
|
*/
|
|
|
|
define(['/static/app/DA-ITSI-CP-vmware-dashboards/libs/backbone.js',
|
|
"/static/app/DA-ITSI-CP-vmware-dashboards/swc-vmware-cp/index.js",
|
|
"pm/PMEventDispatcher",
|
|
"pm/PMPinnedDetailTableView",
|
|
"pm/PMChartView",
|
|
"pm/PMThresholdIndexCellRenderer",
|
|
"pm/PMLeafNameCellRenderer",
|
|
"text!pm/PMPinnedDetail.html",
|
|
'/static/app/DA-ITSI-CP-vmware-dashboards/libs/underscore.js'],
|
|
function ( Backbone, SWCVMware, dispatcher, PinnedDetailTableView, ChartView, PMThresholdIndexCellRenderer, PMLeafNameCellRenderer, PinnedDetailTemplate, _ ) {
|
|
const TokenUtils = SWCVMware.MVCTokenUtils;
|
|
const SearchManager = SWCVMware.SearchManager;
|
|
const mvc = SWCVMware.MVC;
|
|
const TableView = SWCVMware.TableView;
|
|
var template = _.template(PinnedDetailTemplate, null, {variable: "node"});
|
|
var PinnedDetail = Backbone.View.extend({
|
|
tagName: "div",
|
|
className: "proactive-monitoring-pinboard",
|
|
events: {
|
|
"click .pm-pinned-detail-title-bar": "toggleBody",
|
|
"click .pm-pinned-detail-icon-circle.pm-pinned-detail-action-remove": "removeNode",
|
|
"click .pm-pinned-detail-icon-circle.pm-pinned-detail-action-drill": "drillNode"
|
|
},
|
|
options: {
|
|
sidebar_width: 300,
|
|
min_total_height: 800
|
|
},
|
|
type_detail_search_map: {
|
|
"VirtualMachine": '`vmwareinv-index` sourcetype="vmware_inframon:inv:vm" earliest=1 ' +
|
|
'| spath moid output=moid ' +
|
|
'| search moid="$moid$" host="$host$" ' +
|
|
'|spath collectionVersion output=collectionVersion ' +
|
|
'| spath changeSet.name output=name ' +
|
|
'| spath changeSet.summary.runtime.powerState output=powerState ' +
|
|
'| spath changeSet.config.guestFullName output=guestFullName ' +
|
|
'| spath changeSet.guest.toolsStatus output=toolsStatus ' +
|
|
'| spath changeSet.config.hardware.numCPU output=numCPU ' +
|
|
'| spath changeSet.config.hardware.numCoresPerSocket output=numCoresPerSocket ' +
|
|
'| spath changeSet.config.hardware.memoryMB output=memorySizeMB ' +
|
|
'| spath changeSet.resourceConfig.cpuAllocation.reservation output=cpuReservation ' +
|
|
'| spath changeSet.resourceConfig.memoryAllocation.reservation output=memoryReservation ' +
|
|
'| spath changeSet.resourceConfig.memoryAllocation.shares.level output=memSharesLevel ' +
|
|
'| spath changeSet.resourceConfig.memoryAllocation.shares.shares output=memSharesShares ' +
|
|
'| spath changeSet.resourceConfig.cpuAllocation.shares.level output=cpuSharesLevel ' +
|
|
'| spath changeSet.resourceConfig.cpuAllocation.shares.shares output=cpuSharesShares ' +
|
|
'| spath changeSet.summary.runtime.host.moid output=HostSystem ' +
|
|
'| head (collectionVersion!=1) keeplast=t ' +
|
|
'| stats first(name) AS name, first(powerState) AS powerState, first(numCPU) AS numCPU, first(guestFullName) AS guestFullName, ' +
|
|
'first(toolsStatus) AS toolsStatus, first(numCoresPerSocket) AS numCoresPerSocket, first(memorySizeMB) AS memorySizeMB, ' +
|
|
'first(cpuReservation) AS cpuReservation, first(memoryReservation) AS memoryReservation, first(memSharesLevel) AS memSharesLevel, ' +
|
|
'first(memSharesShares) AS memSharesShares, first(cpuSharesLevel) AS cpuSharesLevel, first(cpuSharesShares) AS cpuSharesShares, ' +
|
|
'first(HostSystem) AS HostSystem first(_time) AS _time by moid, host ' +
|
|
'| fillnull value="Not Available" powerState numCoresPerSocket memorySizeMB cpuSharesShares memSharesShares memoryReservation cpuReservation numCPU ' +
|
|
'| eval cpuSharesLevel=if(isnull(cpuSharesLevel), "Not Available", cpuSharesLevel) ' +
|
|
'| eval memSharesLevel=if(isnull(memSharesLevel), "Not Available", memSharesLevel) ' +
|
|
'| eval guestFullName=if(isnull(guestFullName), "Not Available", guestFullName) ' +
|
|
'| eval toolsStatus=if(isnull(toolsStatus), "Not Available", toolsStatus) ' +
|
|
'| fields - moid,host,name,HostSystem,_time',
|
|
"HostSystem": '`vmwareinv-index` sourcetype="vmware_inframon:inv:hostsystem" earliest=1 ' +
|
|
'| spath moid output=moid ' +
|
|
'| spath changeSet.name output=name ' +
|
|
'| search moid="$moid$" host="$host$" ' +
|
|
'| spath collectionVersion output=collectionVersion ' +
|
|
'| spath changeSet.summary.overallStatus output=overallStatus ' +
|
|
'| spath changeSet.summary.quickStats.overallCpuUsage output=overallCpuUsage ' +
|
|
'| spath changeSet.summary.quickStats.overallMemoryUsage output=overallMemoryUsage ' +
|
|
'| spath changeSet.summary.hardware.cpuMhz output=cpuMhz ' +
|
|
'| spath changeSet.summary.hardware.memorySize output=memorySize ' +
|
|
'| spath changeSet.summary.hardware.numCpuCores output=CPUCores ' +
|
|
'| spath changeSet.summary.hardware.vendor output=manufacturer ' +
|
|
'| spath changeSet.summary.hardware.model output=model | spath changeSet.summary.hardware.numNics output=numNics ' +
|
|
'| spath changeSet.summary.hardware.cpuModel output=processorType | spath changeSet.summary.hardware.numCpuPkgs output=numCpuPkgs ' +
|
|
'| spath changeSet.summary.hardware.numCpuThreads output=logicalProcessor | spath changeSet.config.hyperThread.active output=active ' +
|
|
'| spath changeSet.summary.host.moid output=HostSystem | spath changeSet.parent.moid output=HostSystemParent ' +
|
|
'| spath changeSet.parent.type output=HostSystemParentType | head (collectionVersion!=1) keeplast=t ' +
|
|
'| stats first(overallStatus) As overallStatus first(manufacturer) As Manufacturer first(model) As Model first(numNics) As NumberofNICs ' +
|
|
'first(logicalProcessor) As LogicalProcessors first(processorType) As ProcessorType first(numCpuPkgs) As ProcessorSockets ' +
|
|
'first(overallMemoryUsage) AS MemUsg first(overallCpuUsage) AS CpuUsg first(cpuMhz) AS MhzPerCore first(memorySize) AS Mem first(CPUCores) as CPUCores' +
|
|
' first(name) As Host first(HostSystem) AS HostSystem first(HostSystemParent) As HostSystemParent first(HostSystemParentType) As HostSystemParentType first(active) as active by moid, host' +
|
|
'| eval MaxCpuMhz=MhzPerCore*CPUCores ' +
|
|
'| eval MaxMemMB=((Mem/1024)/1024) ' +
|
|
'| eval FreeMem=MaxMemMB-MemUsg ' +
|
|
'| eval FreeCpu=MaxCpuMhz-CpuUsg ' +
|
|
'| eval CoresperSocket=CPUCores/ProcessorSockets ' +
|
|
'| eval Hyperthreading=if(active="True", "Active", "Inactive") ' +
|
|
'| fillnull value="N/A" overallStatus, Manufacturer, Model, NumberofNICs,LogicalProcessors,ProcessorType, ProcessorSockets, MemUsg, CpuUsg, MhzPerCore, Mem, CPUCores, CoresperSocket, FreeCpu, FreeMem, Hyperthreading, MaxCpuMhz, MaxMemMB' +
|
|
'| fields - count,Host,HostSystemParent,HostSystem,HostSystemParentType,moid,host,Mem,active',
|
|
"ClusterComputeResource": '| stats count ' +
|
|
'| eval moid="$moid$" ' +
|
|
'| eval host="$host$" ' +
|
|
'| `HandleInfoMaxTimeNow` ' +
|
|
'| eval _time=info_max_time ' +
|
|
'| lookup TimeClusterServicesAvailability moid, host OUTPUT p_average_clusterServices_effectivecpu_megaHertz p_average_clusterServices_effectivemem_megaBytes ' +
|
|
'| lookup FullHierarchy moid, host OUTPUT name | rename p_average_clusterServices_effectivecpu_megaHertz as AvgEffCpu_MHz ' +
|
|
'| eval AvgEffMem=`format_bytes(p_average_clusterServices_effectivemem_megaBytes*1024*1024)` ' +
|
|
'| eval AvgEffCpu_MHz=if(isnull(AvgEffCpu_MHz),"Unavailable",AvgEffCpu_MHz) ' +
|
|
'| table AvgEffCpu_MHz AvgEffMem',
|
|
"RootFolder": '`vmwareinv-index` sourcetype=vmware_inframon:inv:hierarchy earliest=-8h latest=now host=$host$ "\\"type\\": \\"VirtualMachine\\"" OR "\\"type\\": \\"HostSystem\\"" OR "\\"type\\": \\"ClusterComputeResource\\"" ' +
|
|
'| dedup moid | stats count(eval(type="HostSystem")) AS Hosts count(eval(type="VirtualMachine")) as VirtualMachines count(eval(type="ClusterComputeResource")) as Clusters'
|
|
},
|
|
specific_performance_search: '| mstats span=1m avg(_value) as avgValue ' +
|
|
'where metric_name=vsphere.$metric_entity$.$perf_type$.$metric_type$ AND `vmwareperf-metrics-index` AND source="VMPerf:$perf_source$" ' +
|
|
'AND instance="aggregated" AND unit="$unit$" AND (moid="$moid$" AND host="$host$") by vmware_metric_aggregation ' +
|
|
'| eval avg_$metric_type$_$unit$ =if(vmware_metric_aggregation="$metric_aggregation$",avgValue,NULL) ' +
|
|
'| timechart minspan=1m avg(avg_$metric_type$_$unit$) AS metric',
|
|
parent_performance_search: '| mstats span=1m avg(_value) as avgValue ' +
|
|
'where metric_name=vsphere.$metric_entity$.$perf_type$.$metric_type$ AND `vmwareperf-metrics-index` AND source="VMPerf:$perf_source$" ' +
|
|
'AND unit="$unit$" AND (moid="$moid$" AND host="$host$") ' +
|
|
'OR (hypervisor="$moid$" AND host="$host$") OR (cluster="$moid$" AND host="$host$") instance="aggregated" by host moid vmware_metric_aggregation ' +
|
|
'| eval avg_$metric_type$_$unit$ =if(vmware_metric_aggregation="$metric_aggregation$",avgValue,NULL) ' +
|
|
'| stats avg(avg_$metric_type$_$unit$) AS avg_metric by host, moid |stats sparkline(avg(avg_metric), 5m) AS sparkline avg(avg_metric) AS avg_metric by host, moid ' +
|
|
'| $threshold_snippet$ ' +
|
|
'| eval _time=now() ' +
|
|
'| lookup FullHierarchy moid, host OUTPUT name ' +
|
|
'| table threshold_index, name, sparkline ' +
|
|
'| sort threshold_index ' +
|
|
'| rename threshold_index AS s ' +
|
|
'| head 50',
|
|
node: undefined,
|
|
pinboard_controller: undefined,
|
|
detail_manager: undefined,
|
|
initialize: function (options) {
|
|
this.node = options.node;
|
|
this.pinboard_controller = options.pinboard_controller;
|
|
this.pin_id = options.pin_id;
|
|
this.distribution_search_id = options.distribution_search_id;
|
|
|
|
Backbone.View.prototype.initialize.apply(this, arguments);
|
|
},
|
|
/*
|
|
* Render all the things!
|
|
*/
|
|
render: function () {
|
|
this.$el.html(template(this.node, {variable: "node"}));
|
|
|
|
//Freeze Tokens at current values for pinned searches
|
|
var submitted_tokens = mvc.Components.get('submitted');
|
|
var entitytype = submitted_tokens.get("entity_type");
|
|
var earliest = submitted_tokens.get("earliest");
|
|
var latest = submitted_tokens.get("latest");
|
|
|
|
//Set Metric in View
|
|
this.$(".pm-pinned-detail-metric-section").text(submitted_tokens.get("metric"));
|
|
|
|
//Detail Info Search and View
|
|
var detail_manager_id = this.node.id + "-detail-" + this.cid;
|
|
this.detail_manager = new SearchManager({
|
|
id: detail_manager_id,
|
|
earliest_time: earliest,
|
|
latest_time: latest,
|
|
preview: false,
|
|
cache: 600,
|
|
status_buckets: 0,
|
|
search: this._getDetailSearch(),
|
|
time_format: "%s.%Q"
|
|
}, {tokens: false});
|
|
|
|
this.detail_view = new PinnedDetailTableView({
|
|
el: this.$(".pm-pinned-detail-detail-section"),
|
|
managerid: detail_manager_id
|
|
});
|
|
|
|
//Chart Search and View
|
|
var chart_manager_id = this.node.id + "-chart-" + this.cid;
|
|
var search_snippet;
|
|
if (this.node.type.toLowerCase() === entitytype) {
|
|
//For leaf node show the distribution graph
|
|
search_snippet = this.specific_performance_search.replace(/\$moid\$/g, this.node.node_id).replace(/\$host\$/g, this.node.tree);
|
|
this.chart_search = new SearchManager({
|
|
id: chart_manager_id,
|
|
earliest_time: earliest,
|
|
latest_time: latest,
|
|
preview: false,
|
|
cache: 600,
|
|
status_buckets: 0,
|
|
search: TokenUtils.replaceTokens(search_snippet, mvc.Components, {tokenNamespace: "submitted"}),
|
|
time_format: "%s.%Q"
|
|
}, {tokens: false});
|
|
|
|
this.chart_view = new ChartView({
|
|
el: this.$(".pm-pinned-detail-chart-section"),
|
|
color_scheme: "light",
|
|
plot_width: 230,
|
|
distribution_managerid: this.distribution_search_id,
|
|
specific_managerid: chart_manager_id
|
|
});
|
|
this.chart_view.render();
|
|
}
|
|
else {
|
|
//For parent node show sparklines
|
|
search_snippet = this.parent_performance_search.replace(/\$moid\$/g, this.node.node_id).replace(/\$host\$/g, this.node.tree);
|
|
this.chart_search = new SearchManager({
|
|
id: chart_manager_id,
|
|
earliest_time: earliest,
|
|
latest_time: latest,
|
|
preview: true,
|
|
cache: 600,
|
|
status_buckets: 0,
|
|
search: TokenUtils.replaceTokens(search_snippet, mvc.Components, {tokenNamespace: "submitted"}),
|
|
time_format: "%s.%Q"
|
|
}, {tokens: false});
|
|
|
|
this.chart_view = new TableView({
|
|
id: this.node.id + "-table-" + this.cid,
|
|
managerid: chart_manager_id,
|
|
format: {
|
|
sparkline: [
|
|
{
|
|
type: "sparkline",
|
|
options: {
|
|
width: "100px",
|
|
lineColor: "#BCBCBC"
|
|
}
|
|
}
|
|
]
|
|
},
|
|
pageSize: 10,
|
|
pagerPosition: "bottom",
|
|
showPager: true,
|
|
el: this.$(".pm-pinned-detail-chart-section")
|
|
}).render();
|
|
|
|
this.chart_view.table.addCellRenderer(new PMThresholdIndexCellRenderer());
|
|
this.chart_view.table.addCellRenderer(new PMLeafNameCellRenderer());
|
|
this.chart_view.table.render();
|
|
}
|
|
},
|
|
_getDetailSearch: function () {
|
|
var base_search = this.type_detail_search_map[this.node.type];
|
|
return base_search.replace(/\$moid\$/g, this.node.node_id).replace(/\$host\$/g, this.node.tree);
|
|
},
|
|
//
|
|
// EVENT CALLBACKS
|
|
//
|
|
toggleBody: function () {
|
|
console.log("[PMPinnedDetail] toggle body called on node:" + this.node.name);
|
|
var that = this;
|
|
this.$(".pm-pinned-detail-body").slideToggle(function () {
|
|
var $this = $(this);
|
|
if ($this.css("display") === "none") {
|
|
that.$(".pm-pinned-detail-title-bar").css("border-bottom", "1px solid #CCCCCC");
|
|
}
|
|
else {
|
|
that.$(".pm-pinned-detail-title-bar").css("border-bottom", "none");
|
|
}
|
|
});
|
|
},
|
|
removeNode: function (e) {
|
|
//Stop toggle from triggering
|
|
e.stopPropagation();
|
|
console.log("[PMPinnedDetail] remove called on node:" + this.node.name);
|
|
|
|
//Clean up detail info
|
|
this.detail_manager.set("cancelOnUnload", false);
|
|
this.detail_manager.cancel();
|
|
this.detail_manager.off();
|
|
mvc.Components.revokeInstance(this.detail_manager.id);
|
|
this.detail_view.off();
|
|
this.detail_view.remove();
|
|
|
|
//Unregister with controller
|
|
this.pinboard_controller.removePin(this.pin_id);
|
|
|
|
//Remove this view
|
|
this.off();
|
|
this.remove();
|
|
},
|
|
drillNode: function (e) {
|
|
//Stop toggle from triggering
|
|
e.stopPropagation();
|
|
console.log("[PMPinnedDetail] drill called on node:" + this.node.name);
|
|
|
|
dispatcher.trigger("node:drill", this.node);
|
|
}
|
|
});
|
|
|
|
return PinnedDetail;
|
|
}); |