Working on cache rewriting (remove config caching).

This commit is contained in:
Alexander Zobnin
2016-03-25 19:40:22 +03:00
parent 9c04b11886
commit cf07d7c2df
4 changed files with 252 additions and 78 deletions

View File

@@ -14,6 +14,10 @@ export class ZabbixQueryController extends QueryCtrl {
// Call superclass constructor // Call superclass constructor
super($scope, $injector); super($scope, $injector);
this.zabbix = this.datasource.zabbixAPI;
this.cache = this.datasource.zabbixCache;
this.$q = $q;
this.editorModes = { this.editorModes = {
0: 'num', 0: 'num',
1: 'itservice', 1: 'itservice',
@@ -22,9 +26,9 @@ export class ZabbixQueryController extends QueryCtrl {
// Map functions for bs-typeahead // Map functions for bs-typeahead
this.getGroupNames = _.partial(getMetricNames, this, 'groupList'); this.getGroupNames = _.partial(getMetricNames, this, 'groupList');
this.getHostNames = _.partial(getMetricNames, this, 'filteredHosts'); this.getHostNames = _.partial(getMetricNames, this, 'hostList');
this.getApplicationNames = _.partial(getMetricNames, this, 'filteredApplications'); this.getApplicationNames = _.partial(getMetricNames, this, 'appList');
this.getItemNames = _.partial(getMetricNames, this, 'filteredItems'); this.getItemNames = _.partial(getMetricNames, this, 'itemList');
this.init = function() { this.init = function() {
@@ -32,7 +36,8 @@ export class ZabbixQueryController extends QueryCtrl {
var target = this.target; var target = this.target;
var scopeDefaults = { var scopeDefaults = {
metric: {} metric: {},
oldTarget: _.cloneDeep(this.target)
}; };
_.defaults(this, scopeDefaults); _.defaults(this, scopeDefaults);
@@ -85,49 +90,86 @@ export class ZabbixQueryController extends QueryCtrl {
} }
initFilters() { initFilters() {
this.filterGroups(); var self = this;
this.filterHosts(); return this.$q.when(this.suggestGroups())
this.filterApplications(); .then(() => {return self.suggestHosts();})
this.filterItems(); .then(() => {return self.suggestApps();})
.then(() => {return self.suggestItems();});
} }
filterHosts() { suggestGroups() {
var self = this; var self = this;
var groupFilter = this.templateSrv.replace(this.target.group.filter); return this.cache.getGroups().then(groups => {
this.datasource.queryProcessor.filterHosts(groupFilter).then(function(hosts) {
self.metric.filteredHosts = hosts;
});
}
filterGroups() {
var self = this;
this.datasource.queryProcessor.filterGroups().then(function(groups) {
self.metric.groupList = groups; self.metric.groupList = groups;
return groups;
}); });
} }
filterApplications() { suggestHosts() {
var self = this; var self = this;
var groupFilter = this.templateSrv.replace(this.target.group.filter); var groupFilter = this.templateSrv.replace(this.target.group.filter);
var hostFilter = this.templateSrv.replace(this.target.host.filter); return this.datasource.queryProcessor
this.datasource.queryProcessor.filterApplications(groupFilter, hostFilter) .filterGroups(self.metric.groupList, groupFilter)
.then(function(apps) { .then(groups => {
self.metric.filteredApplications = apps; var groupids = _.map(groups, 'groupid');
return self.zabbix
.getHostsByGroups(groupids)
.then(hosts => {
self.metric.hostList = hosts;
return hosts;
});
}); });
} }
filterItems() { suggestApps() {
var self = this; var self = this;
var item_type = this.editorModes[this.target.mode];
var groupFilter = this.templateSrv.replace(this.target.group.filter);
var hostFilter = this.templateSrv.replace(this.target.host.filter); var hostFilter = this.templateSrv.replace(this.target.host.filter);
var appFilter = this.templateSrv.replace(this.target.application.filter); return this.datasource.queryProcessor
this.datasource.queryProcessor.filterItems(groupFilter, hostFilter, appFilter, .filterHosts(self.metric.hostList, hostFilter)
item_type, this.target.showDisabledItems).then(function(items) { .then(hosts => {
self.metric.filteredItems = items; var hostids = _.map(hosts, 'hostid');
return self.zabbix
.getApps(hostids)
.then(apps => {
return self.metric.appList = apps;
});
}); });
} }
suggestItems() {
var self = this;
var appFilter = this.templateSrv.replace(this.target.application.filter);
if (appFilter) {
// Filter by applications
return this.datasource.queryProcessor
.filterApps(self.metric.appList, appFilter)
.then(apps => {
var appids = _.map(apps, 'applicationid');
return self.zabbix
.getItems(undefined, appids)
.then(items => {
if (!self.target.showDisabledItems) {
items = _.filter(items, {'status': '0'});
}
self.metric.itemList = items;
return items;
});
});
} else {
// Return all items belonged to selected hosts
var hostids = _.map(self.metric.hostList, 'hostid');
return self.zabbix
.getItems(hostids)
.then(items => {
if (!self.target.showDisabledItems) {
items = _.filter(items, {'status': '0'});
}
self.metric.itemList = items;
return items;
});
}
}
onTargetPartChange(targetPart) { onTargetPartChange(targetPart) {
var regexStyle = {'color': '#CCA300'}; var regexStyle = {'color': '#CCA300'};
targetPart.isRegex = utils.isRegex(targetPart.filter); targetPart.isRegex = utils.isRegex(targetPart.filter);
@@ -135,9 +177,13 @@ export class ZabbixQueryController extends QueryCtrl {
} }
onTargetBlur() { onTargetBlur() {
this.initFilters(); var newTarget = _.cloneDeep(this.target);
this.parseTarget(); if (!_.isEqual(this.oldTarget, this.target)) {
this.panelCtrl.refresh(); this.oldTarget = newTarget;
this.initFilters();
this.parseTarget();
this.panelCtrl.refresh();
}
} }
parseTarget() { parseTarget() {

View File

@@ -39,31 +39,26 @@ angular.module('grafana.services').factory('QueryProcessor', function($q) {
} }
} }
filterGroups(groupFilter) { filterGroups(groups, groupFilter) {
return this.cache.getGroups().then(function(groupList) { return this.$q.when(
return groupList; findByFilter(groups, groupFilter)
}); );
} }
/** /**
* Get list of host belonging to given groups. * Get list of host belonging to given groups.
* @return list of hosts * @return list of hosts
*/ */
filterHosts(groupFilter) { filterHosts(hosts, hostFilter) {
var self = this; return this.$q.when(
return this.cache.getGroups().then(function(groups) { findByFilter(hosts, hostFilter)
groups = findByFilter(groups, groupFilter); );
var hostids = _.flatten(_.map(groups, 'hosts')); }
if (hostids.length) {
return self.cache.getIndexedHosts().then(function(hosts) { filterApps(apps, appFilter) {
return _.map(hostids, function(hostid) { return this.$q.when(
return hosts[hostid]; findByFilter(apps, appFilter)
}); );
});
} else {
return [];
}
});
} }
/** /**
@@ -151,10 +146,65 @@ angular.module('grafana.services').factory('QueryProcessor', function($q) {
}); });
} }
buildFromCache(groupFilter, hostFilter, appFilter, itemFilter, showDisabledItems) {
var self = this;
return this.cache
.getGroups()
.then(groups => {
return findByFilter(groups, groupFilter);
})
.then(groups => {
var groupids = _.map(groups, 'groupid');
return self.cache
.getHosts(groupids)
.then(hosts => {
return findByFilter(hosts, hostFilter);
});
})
.then(hosts => {
var hostids = _.map(hosts, 'hostid');
if (appFilter) {
return self.cache
.getApps(hostids)
.then(apps => {
// Use getByFilter for proper item filtering
return getByFilter(apps, appFilter);
});
} else {
return {
appFilterEmpty: true,
hostids: hostids
};
}
})
.then(apps => {
if (apps.appFilterEmpty) {
return self.cache
.getItems(apps.hostids)
.then(items => {
if (showDisabledItems) {
items = _.filter(items, {'status': '0'});
}
return getByFilter(items, itemFilter);
});
} else {
var appids = _.map(apps, 'applicationid');
return self.cache
.getItems(undefined, appids)
.then(items => {
if (showDisabledItems) {
items = _.filter(items, {'status': '0'});
}
return getByFilter(items, itemFilter);
});
}
});
}
/** /**
* Build query - convert target filters to array of Zabbix items * Build query - convert target filters to array of Zabbix items
*/ */
buildFromCache(groupFilter, hostFilter, appFilter, itemFilter) { _buildFromCache(groupFilter, hostFilter, appFilter, itemFilter) {
return this.filterItems(groupFilter, hostFilter, appFilter).then(function(items) { return this.filterItems(groupFilter, hostFilter, appFilter).then(function(items) {
if (items.length) { if (items.length) {
if (utils.isRegex(itemFilter)) { if (utils.isRegex(itemFilter)) {
@@ -309,6 +359,23 @@ function findByName(list, name) {
} }
} }
/**
* Different hosts can contains applications and items with same name.
* For this reason use _.filter, which return all elements instead _.find,
* which return only first finded.
* @param {[type]} list list of elements
* @param {[type]} name app name
* @return {[type]} array with finded element or undefined
*/
function filterByName(list, name) {
var finded = _.filter(list, {'name': name});
if (finded) {
return finded;
} else {
return undefined;
}
}
function findByRegex(list, regex) { function findByRegex(list, regex) {
var filterPattern = utils.buildRegex(regex); var filterPattern = utils.buildRegex(regex);
return _.filter(list, function (zbx_obj) { return _.filter(list, function (zbx_obj) {
@@ -324,6 +391,14 @@ function findByFilter(list, filter) {
} }
} }
function getByFilter(list, filter) {
if (utils.isRegex(filter)) {
return findByRegex(list, filter);
} else {
return filterByName(list, filter);
}
}
function getFromIndex(index, objids) { function getFromIndex(index, objids) {
return _.map(objids, function(id) { return _.map(objids, function(id) {
return index[id]; return index[id];

View File

@@ -1,5 +1,6 @@
import angular from 'angular'; import angular from 'angular';
import _ from 'lodash'; import _ from 'lodash';
import * as utils from './utils';
import './zabbixAPICore.service'; import './zabbixAPICore.service';
/** @ngInject */ /** @ngInject */
@@ -116,24 +117,42 @@ function ZabbixAPIService($q, alertSrv, zabbixAPICoreService) {
getGroups() { getGroups() {
var params = { var params = {
output: ['name'], output: ['name'],
sortfield: 'name', sortfield: 'name'
selectHosts: []
}; };
return this.request('hostgroup.get', params); return this.request('hostgroup.get', params);
} }
getHosts() { getHosts(groupids) {
var params = { var params = {
output: ['name', 'host'], output: ['name', 'host'],
sortfield: 'name', sortfield: 'name'
selectGroups: [], };
selectApplications: ['applicationid'] if (groupids) {
params.groupids = groupids;
}
return this.request('host.get', params);
}
getHostsByGroups(groupids) {
var params = {
output: ['name', 'host'],
groupids: groupids
}; };
return this.request('host.get', params); return this.request('host.get', params);
} }
getApps(hostids) {
var params = {
output: ['applicationid', 'name'],
hostids: hostids
};
return this.request('application.get', params);
}
getApplications() { getApplications() {
var params = { var params = {
output: ['applicationid', 'name'], output: ['applicationid', 'name'],
@@ -147,7 +166,7 @@ function ZabbixAPIService($q, alertSrv, zabbixAPICoreService) {
return this.request('application.get', params); return this.request('application.get', params);
} }
getItems() { getItems(hostids, appids) {
var params = { var params = {
output: [ output: [
'name', 'key_', 'name', 'key_',
@@ -157,10 +176,22 @@ function ZabbixAPIService($q, alertSrv, zabbixAPICoreService) {
'state' 'state'
], ],
sortfield: 'name', sortfield: 'name',
selectApplications: []
}; };
if (hostids) {
params.hostids = hostids;
}
if (appids) {
params.applicationids = appids;
}
return this.request('item.get', params); return this.request('item.get', params)
.then(items => {
return _.forEach(items, item => {
item.item = item.name;
item.name = utils.expandItemName(item.item, item.key_);
return item;
});
});
} }
/** /**

View File

@@ -45,21 +45,12 @@ angular.module('grafana.services').factory('ZabbixCachingProxy', function($q, $i
_refresh() { _refresh() {
var self = this; var self = this;
var promises = [ var promises = [
this.zabbixAPI.getGroups(), this.zabbixAPI.getGroups()
this.zabbixAPI.getHosts(),
this.zabbixAPI.getApplications(),
this.zabbixAPI.getItems(),
this.zabbixAPI.getHostsExtend()
]; ];
return this.$q.all(promises).then(function(results) { return this.$q.all(promises).then(function(results) {
if (results.length) { if (results.length) {
self._groups = convertGroups(results[0]); self._groups = results[0];
self._hosts = convertHosts(results[1]);
self._applications = convertApplications(results[2]);
self._items = convertItems(results[3]);
self._idx_apps = indexApps(results[2]);
self._idx_hosts = indexHosts(results[4]);
} }
self._initialized = true; self._initialized = true;
}); });
@@ -70,13 +61,44 @@ angular.module('grafana.services').factory('ZabbixCachingProxy', function($q, $i
if (this._groups) { if (this._groups) {
return this.$q.when(self._groups); return this.$q.when(self._groups);
} else { } else {
return this.refresh().then(function() { return this.zabbixAPI
return self._groups; .getGroups()
}); .then(groups => {
self._groups = groups;
return self._groups;
});
} }
} }
getHosts() { getApps(hostids) {
return this.zabbixAPI
.getApps(hostids)
.then(apps => {
return apps;
});
}
getHosts(groupids) {
var self = this;
return this.zabbixAPI
.getHosts(groupids)
.then(hosts => {
self._hosts = _.union(self._hosts, hosts);
return hosts;
});
}
getItems(hostids, appids) {
var self = this;
return this.zabbixAPI
.getItems(hostids, appids)
.then(items => {
self._items = _.union(self._items, items);
return items;
});
}
_getHosts() {
var self = this; var self = this;
if (this._hosts) { if (this._hosts) {
return this.$q.when(self._hosts); return this.$q.when(self._hosts);
@@ -120,7 +142,7 @@ angular.module('grafana.services').factory('ZabbixCachingProxy', function($q, $i
} }
} }
getItems(type) { _getItems(type) {
var self = this; var self = this;
if (this._items) { if (this._items) {
return this.$q.when(filterItems(self._items, type)); return this.$q.when(filterItems(self._items, type));