Resolved #71 - Text metrics support for singlestat panel.

This commit is contained in:
Alexander Zobnin
2015-08-18 23:31:19 +03:00
4 changed files with 147 additions and 105 deletions

View File

@@ -94,7 +94,7 @@ function (angular, _, kbn) {
// Create request for each target // Create request for each target
var promises = _.map(options.targets, function(target) { var promises = _.map(options.targets, function(target) {
if (!target.ITService) { if (target.mode !== 1) {
// Don't show undefined and hidden targets // Don't show undefined and hidden targets
if (target.hide || !target.group || !target.host if (target.hide || !target.group || !target.host
|| !target.application || !target.item) { || !target.application || !target.item) {
@@ -119,8 +119,12 @@ function (angular, _, kbn) {
var delete_hostname_pattern = /(?:\[[\w\.]+]:\s)/g; var delete_hostname_pattern = /(?:\[[\w\.]+]:\s)/g;
var itemnames = zabbixHelperSrv.splitMetrics(itemname.replace(delete_hostname_pattern, '')); var itemnames = zabbixHelperSrv.splitMetrics(itemname.replace(delete_hostname_pattern, ''));
// Find items by item names and perform queries
var self = this; var self = this;
// Query numeric data
if (!target.mode) {
// Find items by item names and perform queries
return this.zabbixAPI.itemFindQuery(groups, hosts, apps) return this.zabbixAPI.itemFindQuery(groups, hosts, apps)
.then(function (items) { .then(function (items) {
@@ -199,7 +203,31 @@ function (angular, _, kbn) {
}); });
} }
}); });
} else { }
// Query text data
else if (target.mode === 2) {
// Find items by item names and perform queries
return this.zabbixAPI.itemFindQuery(groups, hosts, apps, "text")
.then(function (items) {
items = _.filter(items, function (item) {
return _.contains(itemnames, zabbixHelperSrv.expandItemName(item));
});
return self.zabbixAPI.getHistory(items, from, to).then(function(history) {
return {
target: target.item.name,
datapoints: _.map(history, function (p) {
return [p.value, p.clock * 1000];
})
};
});
});
}
}
// IT services mode
else if (target.mode === 1) {
// Don't show undefined and hidden targets // Don't show undefined and hidden targets
if (target.hide || !target.itservice || !target.slaProperty) { if (target.hide || !target.itservice || !target.slaProperty) {
return []; return [];

View File

@@ -16,14 +16,18 @@
<i class="fa fa-bars"></i> <i class="fa fa-bars"></i>
</a> </a>
<ul class="dropdown-menu pull-right" role="menu"> <ul class="dropdown-menu pull-right" role="menu">
<!-- Switch to IT Services editor --> <!-- Switch editor mode -->
<li role="menuitem" ng-hide="target.mode == 1"> <li role="menuitem" ng-show="target.mode">
<a class="pointer" tabindex="1"
ng-click="switchEditorMode(0)">Numeric metrics</a>
</li>
<li role="menuitem" ng-show="target.mode != 1">
<a class="pointer" tabindex="1" <a class="pointer" tabindex="1"
ng-click="switchEditorMode(1)">IT services</a> ng-click="switchEditorMode(1)">IT services</a>
</li> </li>
<li role="menuitem" ng-show="target.mode"> <li role="menuitem" ng-show="target.mode != 2">
<a class="pointer" tabindex="1" <a class="pointer" tabindex="1"
ng-click="switchEditorMode(0)">Items</a> ng-click="switchEditorMode(2)">Text metrics</a>
</li> </li>
<li class="divider" role="menuitem"></li> <li class="divider" role="menuitem"></li>
<li role="menuitem"><a tabindex="1" ng-click="duplicate()">Duplicate</a></li> <li role="menuitem"><a tabindex="1" ng-click="duplicate()">Duplicate</a></li>
@@ -75,7 +79,7 @@
</li> </li>
</ul> </ul>
<ul class="tight-form-list" role="menu" ng-hide="target.mode"> <ul class="tight-form-list" role="menu" ng-hide="target.mode == 1">
<!-- Alias --> <!-- Alias -->
<li> <li>
<input type="text" <input type="text"
@@ -118,12 +122,12 @@
</a> </a>
</li> </li>
<!-- Host filter --> <!-- Host filter -->
<li class="tight-form-item"> <li class="tight-form-item" ng-hide="target.mode == 2">
Filter Filter
<i class="fa fa-question-circle" <i class="fa fa-question-circle"
bs-tooltip="'Filtering hosts by regex. Select All in items and specify regex for host names.'"></i> bs-tooltip="'Filtering hosts by regex. Select All in items and specify regex for host names.'"></i>
</li> </li>
<li> <li ng-hide="target.mode == 2">
<input type="text" <input type="text"
class="tight-form-input input-large" class="tight-form-input input-large"
ng-model="target.hostFilter" ng-model="target.hostFilter"
@@ -132,8 +136,10 @@
ng-blur="targetBlur()"> ng-blur="targetBlur()">
</li> </li>
<!-- Downsampling function --> <!-- Downsampling function -->
<li class="tight-form-item input-medium">Downsampling</li> <li class="tight-form-item input-medium" ng-hide="target.mode == 2">
<li> Downsampling
</li>
<li ng-hide="target.mode == 2">
<select class="tight-form-input input-small" <select class="tight-form-input input-small"
ng-change="targetBlur()" ng-change="targetBlur()"
ng-model="target.downsampleFunction" ng-model="target.downsampleFunction"
@@ -151,7 +157,7 @@
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<div class="tight-form" ng-hide="target.mode"> <div class="tight-form" ng-hide="target.mode == 1">
<ul class="tight-form-list" role="menu"> <ul class="tight-form-list" role="menu">
<li class="tight-form-item" style="min-width: 15px; text-align: center">&nbsp</li> <li class="tight-form-item" style="min-width: 15px; text-align: center">&nbsp</li>
<li class="tight-form-item"> <li class="tight-form-item">
@@ -192,12 +198,12 @@
</a> </a>
</li> </li>
<!-- Item filter --> <!-- Item filter -->
<li class="tight-form-item"> <li class="tight-form-item" ng-hide="target.mode == 2">
Filter Filter
<i class="fa fa-question-circle" <i class="fa fa-question-circle"
bs-tooltip="'Filtering items by regex. Select All in items and specify regex for item names.'"></i> bs-tooltip="'Filtering items by regex. Select All in items and specify regex for item names.'"></i>
</li> </li>
<li> <li ng-hide="target.mode == 2">
<input type="text" <input type="text"
class="tight-form-input input-large" class="tight-form-input input-large"
ng-model="target.itemFilter" ng-model="target.itemFilter"
@@ -206,12 +212,12 @@
ng-blur="targetBlur()"> ng-blur="targetBlur()">
</li> </li>
<!-- Scale --> <!-- Scale -->
<li class="tight-form-item"> <li class="tight-form-item" ng-hide="target.mode == 2">
Scale Scale
<i class="fa fa-question-circle" <i class="fa fa-question-circle"
bs-tooltip="'Set a custom multiplier for series values, for example -1 to invert series'"></i> bs-tooltip="'Set a custom multiplier for series values, for example -1 to invert series'"></i>
</li> </li>
<li> <li ng-hide="target.mode == 2">
<input type="text" <input type="text"
class="tight-form-input input-small" class="tight-form-input input-small"
ng-model="target.scale" ng-model="target.scale"

View File

@@ -13,17 +13,7 @@ define([
$scope.init = function () { $scope.init = function () {
$scope.targetLetters = targetLetters; $scope.targetLetters = targetLetters;
if ($scope.target.mode === 1) { if (!$scope.target.mode || $scope.target.mode !== 1) {
$scope.slaPropertyList = [
{name: "Status", property: "status"},
{name: "SLA", property: "sla"},
{name: "OK time", property: "okTime"},
{name: "Problem time", property: "problemTime"},
{name: "Down time", property: "downtimeTime"}
];
$scope.itserviceList = [{name: "test"}];
$scope.updateITServiceList();
} else {
$scope.downsampleFunctionList = [ $scope.downsampleFunctionList = [
{name: "avg", value: "avg"}, {name: "avg", value: "avg"},
{name: "min", value: "min"}, {name: "min", value: "min"},
@@ -34,12 +24,14 @@ define([
if (!$scope.target.downsampleFunction) { if (!$scope.target.downsampleFunction) {
$scope.target.downsampleFunction = $scope.downsampleFunctionList[0]; $scope.target.downsampleFunction = $scope.downsampleFunctionList[0];
} }
if (!$scope.metric) {
$scope.metric = { $scope.metric = {
hostGroupList: [], hostGroupList: [],
hostList: [{name: '*', visible_name: 'All'}], hostList: [{name: '*', visible_name: 'All'}],
applicationList: [{name: '*', visible_name: 'All'}], applicationList: [{name: '*', visible_name: 'All'}],
itemList: [{name: 'All'}] itemList: [{name: 'All'}]
}; };
}
// Update host group, host, application and item lists // Update host group, host, application and item lists
$scope.updateGroupList(); $scope.updateGroupList();
@@ -49,6 +41,17 @@ define([
setItemAlias(); setItemAlias();
} }
else if ($scope.target.mode === 1) {
$scope.slaPropertyList = [
{name: "Status", property: "status"},
{name: "SLA", property: "sla"},
{name: "OK time", property: "okTime"},
{name: "Problem time", property: "problemTime"},
{name: "Down time", property: "downtimeTime"}
];
$scope.itserviceList = [{name: "test"}];
$scope.updateITServiceList();
}
$scope.target.errors = validateTarget($scope.target); $scope.target.errors = validateTarget($scope.target);
}; };
@@ -221,8 +224,9 @@ define([
var hosts = $scope.target.host ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined; var hosts = $scope.target.host ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined;
var apps = $scope.target.application ? var apps = $scope.target.application ?
zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.application.name)) : undefined; zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.application.name)) : undefined;
var itemtype = $scope.target.mode === 2 ? "text" : "numeric";
if (groups && hosts && apps) { if (groups && hosts && apps) {
$scope.datasource.zabbixAPI.itemFindQuery(groups, hosts, apps).then(function (items) { $scope.datasource.zabbixAPI.itemFindQuery(groups, hosts, apps, itemtype).then(function (items) {
// Show only unique item names // Show only unique item names
var uniq_items = _.map(_.uniq(items, function (item) { var uniq_items = _.map(_.uniq(items, function (item) {
return zabbixHelperSrv.expandItemName(item); return zabbixHelperSrv.expandItemName(item);

View File

@@ -294,7 +294,7 @@ function (angular, _) {
* @param {string|string[]} groupids /////////////////////////// * @param {string|string[]} groupids ///////////////////////////
* @return {string|string[]} Array of Zabbix API item objects * @return {string|string[]} Array of Zabbix API item objects
*/ */
p.performItemSuggestQuery = function(hostids, applicationids, /* optional */ groupids) { p.performItemSuggestQuery = function(hostids, applicationids, groupids, itemtype) {
var params = { var params = {
output: ['name', 'key_', 'value_type', 'delay'], output: ['name', 'key_', 'value_type', 'delay'],
sortfield: 'name', sortfield: 'name',
@@ -302,13 +302,17 @@ function (angular, _) {
webitems: true, webitems: true,
// Return only numeric items // Return only numeric items
filter: { filter: {
value_type: [0,3] value_type: [0, 3]
}, },
// Return only enabled items // Return only enabled items
monitored: true, monitored: true,
searchByAny: true searchByAny: true
}; };
if (itemtype === "text") {
params.filter.value_type = [1, 2, 4];
}
// Filter by hosts or by groups // Filter by hosts or by groups
if (hostids) { if (hostids) {
params.hostids = hostids; params.hostids = hostids;
@@ -409,7 +413,7 @@ function (angular, _) {
* @param {string or array} apps * @param {string or array} apps
* @return {array} array of Zabbix API item objects * @return {array} array of Zabbix API item objects
*/ */
p.itemFindQuery = function(groups, hosts, apps) { p.itemFindQuery = function(groups, hosts, apps, itemtype) {
var promises = []; var promises = [];
// Get hostids from names // Get hostids from names
@@ -447,7 +451,7 @@ function (angular, _) {
}), 'applicationid'); }), 'applicationid');
} }
return self.performItemSuggestQuery(hostids, applicationids, groupids); return self.performItemSuggestQuery(hostids, applicationids, groupids, itemtype);
}); });
}; };