Handle history response in query builder.
This commit is contained in:
@@ -9,12 +9,12 @@ define([
|
|||||||
'./zabbixCache',
|
'./zabbixCache',
|
||||||
'./queryCtrl'
|
'./queryCtrl'
|
||||||
],
|
],
|
||||||
function (angular, _, dateMath, QueryBuilder) {
|
function (angular, _, dateMath) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
function ZabbixAPIDatasource(instanceSettings, $q, templateSrv, alertSrv,
|
function ZabbixAPIDatasource(instanceSettings, $q, templateSrv, alertSrv,
|
||||||
ZabbixAPI, zabbixHelperSrv, ZabbixCache) {
|
ZabbixAPI, zabbixHelperSrv, ZabbixCache, QueryBuilder) {
|
||||||
|
|
||||||
// General data source settings
|
// General data source settings
|
||||||
this.name = instanceSettings.name;
|
this.name = instanceSettings.name;
|
||||||
@@ -39,6 +39,8 @@ function (angular, _, dateMath, QueryBuilder) {
|
|||||||
// Initialize query builder
|
// Initialize query builder
|
||||||
this.queryBuilder = new QueryBuilder(this.zabbixCache);
|
this.queryBuilder = new QueryBuilder(this.zabbixCache);
|
||||||
|
|
||||||
|
console.log(this.zabbixCache);
|
||||||
|
|
||||||
////////////////////////
|
////////////////////////
|
||||||
// Datasource methods //
|
// Datasource methods //
|
||||||
////////////////////////
|
////////////////////////
|
||||||
@@ -128,19 +130,26 @@ function (angular, _, dateMath, QueryBuilder) {
|
|||||||
alias = templateSrv.replace(target.alias, options.scopedVars);
|
alias = templateSrv.replace(target.alias, options.scopedVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
var history;
|
// Add hostname for items from multiple hosts
|
||||||
|
var addHostName = target.host.isRegex;
|
||||||
|
|
||||||
|
var getHistory;
|
||||||
if ((from < useTrendsFrom) && self.trends) {
|
if ((from < useTrendsFrom) && self.trends) {
|
||||||
|
|
||||||
// Use trends
|
// Use trends
|
||||||
var points = target.downsampleFunction ? target.downsampleFunction.value : "avg";
|
var valueType = target.downsampleFunction ? target.downsampleFunction.value : "avg";
|
||||||
history = self.zabbixAPI.getTrends(items, from, to)
|
getHistory = self.zabbixAPI.getTrends(items, from, to).then(function(history) {
|
||||||
.then(_.bind(zabbixHelperSrv.handleTrendResponse, zabbixHelperSrv, items, alias, target.scale, points));
|
return self.queryBuilder.handleTrends(history, addHostName, valueType);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Use history
|
// Use history
|
||||||
history = self.zabbixAPI.getHistory(items, from, to)
|
getHistory = self.zabbixAPI.getHistory(items, from, to).then(function(history) {
|
||||||
.then(_.bind(zabbixHelperSrv.handleHistoryResponse, zabbixHelperSrv, items, alias, target.scale));
|
return self.queryBuilder.handleHistory(history, addHostName);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return history.then(function (timeseries) {
|
return getHistory.then(function (timeseries) {
|
||||||
var timeseries_data = _.flatten(timeseries);
|
var timeseries_data = _.flatten(timeseries);
|
||||||
return _.map(timeseries_data, function (timeseries) {
|
return _.map(timeseries_data, function (timeseries) {
|
||||||
|
|
||||||
|
|||||||
@@ -6,122 +6,206 @@ define([
|
|||||||
function (angular, _, utils) {
|
function (angular, _, utils) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function QueryBuilder(zabbixCacheInstance) {
|
var module = angular.module('grafana.services');
|
||||||
|
|
||||||
this.cache = zabbixCacheInstance;
|
module.factory('QueryBuilder', function() {
|
||||||
|
|
||||||
this.build = function (groupFilter, hostFilter, appFilter, itemFilter) {
|
function QueryBuilder(zabbixCacheInstance) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
// Find items by item names and perform queries
|
this.cache = zabbixCacheInstance;
|
||||||
var groups = [];
|
|
||||||
var hosts = [];
|
|
||||||
var apps = [];
|
|
||||||
var items = [];
|
|
||||||
|
|
||||||
if (utils.isRegex(hostFilter)) {
|
/**
|
||||||
|
* Build query - convert target filters to array of Zabbix items
|
||||||
|
*/
|
||||||
|
this.build = function (groupFilter, hostFilter, appFilter, itemFilter) {
|
||||||
|
|
||||||
// Filter groups
|
// Find items by item names and perform queries
|
||||||
if (utils.isRegex(groupFilter)) {
|
var groups = [];
|
||||||
var groupPattern = utils.buildRegex(groupFilter);
|
var hosts = [];
|
||||||
groups = _.filter(this.cache.getGroups(), function (groupObj) {
|
var apps = [];
|
||||||
return groupPattern.test(groupObj.name);
|
var items = [];
|
||||||
});
|
|
||||||
} else {
|
if (utils.isRegex(hostFilter)) {
|
||||||
var findedGroup = _.find(this.cache.getGroups(), {'name': groupFilter});
|
|
||||||
if (findedGroup) {
|
// Filter groups
|
||||||
groups.push(findedGroup);
|
if (utils.isRegex(groupFilter)) {
|
||||||
|
var groupPattern = utils.buildRegex(groupFilter);
|
||||||
|
groups = _.filter(this.cache.getGroups(), function (groupObj) {
|
||||||
|
return groupPattern.test(groupObj.name);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
groups = undefined;
|
var findedGroup = _.find(this.cache.getGroups(), {'name': groupFilter});
|
||||||
|
if (findedGroup) {
|
||||||
|
groups.push(findedGroup);
|
||||||
|
} else {
|
||||||
|
groups = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (groups) {
|
||||||
if (groups) {
|
var groupids = _.map(groups, 'groupid');
|
||||||
var groupids = _.map(groups, 'groupid');
|
hosts = _.filter(this.cache.getHosts(), function (hostObj) {
|
||||||
hosts = _.filter(this.cache.getHosts(), function (hostObj) {
|
return _.intersection(groupids, hostObj.groups).length;
|
||||||
return _.intersection(groupids, hostObj.groups).length;
|
});
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// No groups finded
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter hosts
|
|
||||||
var hostPattern = utils.buildRegex(hostFilter);
|
|
||||||
hosts = _.filter(hosts, function (hostObj) {
|
|
||||||
return hostPattern.test(hostObj.name);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var findedHost = _.find(this.cache.getHosts(), {'name': hostFilter});
|
|
||||||
if (findedHost) {
|
|
||||||
hosts.push(findedHost);
|
|
||||||
} else {
|
|
||||||
// No hosts finded
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find items belongs to selected hosts
|
|
||||||
items = _.filter(this.cache.getItems(), function (itemObj) {
|
|
||||||
return _.contains(_.map(hosts, 'hostid'), itemObj.hostid);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (utils.isRegex(itemFilter)) {
|
|
||||||
|
|
||||||
// Filter applications
|
|
||||||
if (utils.isRegex(appFilter)) {
|
|
||||||
var appPattern = utils.buildRegex(appFilter);
|
|
||||||
apps = _.filter(this.cache.getApplications(), function (appObj) {
|
|
||||||
return appPattern.test(appObj.name);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Don't use application filter if it empty
|
|
||||||
else if (appFilter === "") {
|
|
||||||
apps = undefined;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var findedApp = _.find(this.cache.getApplications(), {'name': appFilter});
|
|
||||||
if (findedApp) {
|
|
||||||
apps.push(findedApp);
|
|
||||||
} else {
|
} else {
|
||||||
// No applications finded
|
// No groups finded
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter hosts
|
||||||
|
var hostPattern = utils.buildRegex(hostFilter);
|
||||||
|
hosts = _.filter(hosts, function (hostObj) {
|
||||||
|
return hostPattern.test(hostObj.name);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var findedHost = _.find(this.cache.getHosts(), {'name': hostFilter});
|
||||||
|
if (findedHost) {
|
||||||
|
hosts.push(findedHost);
|
||||||
|
} else {
|
||||||
|
// No hosts finded
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find items belongs to selected applications
|
// Find items belongs to selected hosts
|
||||||
if (apps) {
|
items = _.filter(this.cache.getItems(), function (itemObj) {
|
||||||
var appids = _.flatten(_.map(apps, 'applicationids'));
|
return _.contains(_.map(hosts, 'hostid'), itemObj.hostid);
|
||||||
items = _.filter(items, function (itemObj) {
|
});
|
||||||
return _.intersection(appids, itemObj.applications).length;
|
|
||||||
});
|
if (utils.isRegex(itemFilter)) {
|
||||||
|
|
||||||
|
// Filter applications
|
||||||
|
if (utils.isRegex(appFilter)) {
|
||||||
|
var appPattern = utils.buildRegex(appFilter);
|
||||||
|
apps = _.filter(this.cache.getApplications(), function (appObj) {
|
||||||
|
return appPattern.test(appObj.name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Don't use application filter if it empty
|
||||||
|
else if (appFilter === "") {
|
||||||
|
apps = undefined;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var findedApp = _.find(this.cache.getApplications(), {'name': appFilter});
|
||||||
|
if (findedApp) {
|
||||||
|
apps.push(findedApp);
|
||||||
|
} else {
|
||||||
|
// No applications finded
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find items belongs to selected applications
|
||||||
|
if (apps) {
|
||||||
|
var appids = _.flatten(_.map(apps, 'applicationids'));
|
||||||
|
items = _.filter(items, function (itemObj) {
|
||||||
|
return _.intersection(appids, itemObj.applications).length;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items) {
|
||||||
|
var itemPattern = utils.buildRegex(itemFilter);
|
||||||
|
items = _.filter(items, function (itemObj) {
|
||||||
|
return itemPattern.test(itemObj.name);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// No items finded
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
items = _.filter(items, {'name': hostFilter});
|
||||||
|
if (!items.length) {
|
||||||
|
// No items finded
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items) {
|
// Set host as host name for each item
|
||||||
var itemPattern = utils.buildRegex(itemFilter);
|
items = _.each(items, function (itemObj) {
|
||||||
items = _.filter(items, function (itemObj) {
|
itemObj.host = _.find(hosts, {'hostid': itemObj.hostid}).name;
|
||||||
return itemPattern.test(itemObj.name);
|
});
|
||||||
});
|
|
||||||
} else {
|
return items;
|
||||||
// No items finded
|
};
|
||||||
return [];
|
|
||||||
}
|
/**
|
||||||
} else {
|
* Convert Zabbix API history.get response to Grafana format
|
||||||
items = _.filter(items, {'name': hostFilter});
|
*
|
||||||
if (!items.length) {
|
* @return {Array} Array of timeseries in Grafana format
|
||||||
// No items finded
|
* {
|
||||||
return [];
|
* target: "Metric name",
|
||||||
}
|
* datapoints: [[<value>, <unixtime>], ...]
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
this.convertHistory = function(history, addHostName, convertPointCallback) {
|
||||||
|
/**
|
||||||
|
* Response should be in the format:
|
||||||
|
* data: [
|
||||||
|
* {
|
||||||
|
* target: "Metric name",
|
||||||
|
* datapoints: [[<value>, <unixtime>], ...]
|
||||||
|
* }, ...
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Group history by itemid
|
||||||
|
var grouped_history = _.groupBy(history, 'itemid');
|
||||||
|
|
||||||
|
return _.map(grouped_history, function(hist, itemid) {
|
||||||
|
var item = self.cache.getItem(itemid);
|
||||||
|
var alias = item.name;
|
||||||
|
if (addHostName) {
|
||||||
|
var host = self.cache.getHost(item.hostid);
|
||||||
|
alias = host.name + ": " + alias;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
target: alias,
|
||||||
|
datapoints: _.map(hist, convertPointCallback)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
this.handleHistory = function(history, addHostName) {
|
||||||
|
return this.convertHistory(history, addHostName, convertHistoryPoint);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.handleTrends = function(history, addHostName, valueType) {
|
||||||
|
var convertPointCallback = _.partial(convertTrendPoint, valueType);
|
||||||
|
return this.convertHistory(history, addHostName, convertPointCallback);
|
||||||
|
};
|
||||||
|
|
||||||
|
function convertHistoryPoint(point) {
|
||||||
|
// Value must be a number for properly work
|
||||||
|
return [
|
||||||
|
Number(point.value),
|
||||||
|
point.clock * 1000
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set host as host name for each item
|
function convertTrendPoint(valueType, point) {
|
||||||
items = _.each(items, function (itemObj) {
|
var value;
|
||||||
itemObj.host = _.find(hosts, {'hostid': itemObj.hostid}).name;
|
switch (valueType) {
|
||||||
});
|
case "min":
|
||||||
|
value = point.value_min;
|
||||||
|
break;
|
||||||
|
case "max":
|
||||||
|
value = point.value_max;
|
||||||
|
break;
|
||||||
|
case "avg":
|
||||||
|
value = point.value_avg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
value = point.value_avg;
|
||||||
|
}
|
||||||
|
|
||||||
return items;
|
return [
|
||||||
};
|
Number(value),
|
||||||
|
point.clock * 1000
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
return QueryBuilder;
|
||||||
|
});
|
||||||
return QueryBuilder;
|
|
||||||
|
|
||||||
});
|
});
|
||||||
@@ -118,12 +118,14 @@ function (angular, _) {
|
|||||||
/**
|
/**
|
||||||
* Perform history query from Zabbix API
|
* Perform history query from Zabbix API
|
||||||
*
|
*
|
||||||
* @param {Array} items Array of Zabbix item objects
|
* @param {Array} items Array of Zabbix item objects
|
||||||
* @param {Number} start Time in seconds
|
* @param {Number} time_from Time in seconds
|
||||||
* @param {Number} end Time in seconds
|
* @param {Number} time_till Time in seconds
|
||||||
* @return {Array} Array of Zabbix history objects
|
* @return {Array} Array of Zabbix history objects
|
||||||
*/
|
*/
|
||||||
p.getHistory = function(items, start, end) {
|
p.getHistory = function(items, time_from, time_till) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
// Group items by value type
|
// Group items by value type
|
||||||
var grouped_items = _.groupBy(items, 'value_type');
|
var grouped_items = _.groupBy(items, 'value_type');
|
||||||
|
|
||||||
@@ -136,30 +138,30 @@ function (angular, _) {
|
|||||||
itemids: itemids,
|
itemids: itemids,
|
||||||
sortfield: 'clock',
|
sortfield: 'clock',
|
||||||
sortorder: 'ASC',
|
sortorder: 'ASC',
|
||||||
time_from: start
|
time_from: time_from
|
||||||
};
|
};
|
||||||
|
|
||||||
// Relative queries (e.g. last hour) don't include an end time
|
// Relative queries (e.g. last hour) don't include an end time
|
||||||
if (end) {
|
if (time_till) {
|
||||||
params.time_till = end;
|
params.time_till = time_till;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.request('history.get', params);
|
return self.request('history.get', params);
|
||||||
}, this)).then(function (results) {
|
})).then(_.flatten);
|
||||||
return _.flatten(results);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform trends query from Zabbix API
|
* Perform trends query from Zabbix API
|
||||||
* Use trends api extension from ZBXNEXT-1193 patch.
|
* Use trends api extension from ZBXNEXT-1193 patch.
|
||||||
*
|
*
|
||||||
* @param {Array} items Array of Zabbix item objects
|
* @param {Array} items Array of Zabbix item objects
|
||||||
* @param {Number} start Time in seconds
|
* @param {Number} time_from Time in seconds
|
||||||
* @param {Number} end Time in seconds
|
* @param {Number} time_till Time in seconds
|
||||||
* @return {Array} Array of Zabbix trend objects
|
* @return {Array} Array of Zabbix trend objects
|
||||||
*/
|
*/
|
||||||
p.getTrends = function(items, start, end) {
|
p.getTrends = function(items, time_from, time_till) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
// Group items by value type
|
// Group items by value type
|
||||||
var grouped_items = _.groupBy(items, 'value_type');
|
var grouped_items = _.groupBy(items, 'value_type');
|
||||||
|
|
||||||
@@ -172,18 +174,16 @@ function (angular, _) {
|
|||||||
itemids: itemids,
|
itemids: itemids,
|
||||||
sortfield: 'clock',
|
sortfield: 'clock',
|
||||||
sortorder: 'ASC',
|
sortorder: 'ASC',
|
||||||
time_from: start
|
time_from: time_from
|
||||||
};
|
};
|
||||||
|
|
||||||
// Relative queries (e.g. last hour) don't include an end time
|
// Relative queries (e.g. last hour) don't include an end time
|
||||||
if (end) {
|
if (time_till) {
|
||||||
params.time_till = end;
|
params.time_till = time_till;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.request('trend.get', params);
|
return self.request('trend.get', params);
|
||||||
}, this)).then(function (results) {
|
})).then(_.flatten);
|
||||||
return _.flatten(results);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
p.getITService = function(/* optional */ serviceids) {
|
p.getITService = function(/* optional */ serviceids) {
|
||||||
|
|||||||
@@ -70,6 +70,14 @@ function (angular, _, utils) {
|
|||||||
return this._items;
|
return this._items;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
p.getHost = function(hostid) {
|
||||||
|
return _.find(this._hosts, {'hostid': hostid});
|
||||||
|
};
|
||||||
|
|
||||||
|
p.getItem = function(itemid) {
|
||||||
|
return _.find(this._items, {'itemid': itemid});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert host.get response to cache format
|
* Convert host.get response to cache format
|
||||||
* host.groups - array of group ids
|
* host.groups - array of group ids
|
||||||
|
|||||||
Reference in New Issue
Block a user