Improve tags performance (#1526)
Co-authored-by: Erik De Neve <erik.de.neve@telenet.be>
This commit is contained in:
@@ -70,7 +70,8 @@ export const MetricsQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
}, [query.group.filter, query.host.filter]);
|
||||
|
||||
const loadTagOptions = async (group: string, host: string) => {
|
||||
if (!datasource.zabbix.isZabbix54OrHigher()) {
|
||||
const tagsAvailable = await datasource.zabbix.isZabbix54OrHigher();
|
||||
if (!tagsAvailable) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -78,6 +79,7 @@ export const MetricsQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
const hostFilter = datasource.replaceTemplateVars(host);
|
||||
const items = await datasource.zabbix.getAllItems(groupFilter, hostFilter, null, null, {});
|
||||
const tags: ZBXItemTag[] = _.flatten(items.map((item: ZBXItem) => item.tags || []));
|
||||
// const tags: ZBXItemTag[] = await datasource.zabbix.getItemTags(groupFilter, hostFilter, null);
|
||||
|
||||
const tagList = _.uniqBy(tags, (t) => t.tag + t.value || '').map((t) => itemTagToString(t));
|
||||
let options: Array<SelectableValue<string>> = tagList?.map((tag) => ({
|
||||
|
||||
@@ -85,7 +85,8 @@ export const TriggersQueryEditor = ({ query, datasource, onChange }: Props) => {
|
||||
}, [query.group.filter, query.host.filter]);
|
||||
|
||||
const loadTagOptions = async (group: string, host: string) => {
|
||||
if (!datasource.zabbix.isZabbix54OrHigher()) {
|
||||
const tagsAvailable = await datasource.zabbix.isZabbix54OrHigher();
|
||||
if (!tagsAvailable) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
@@ -87,10 +87,10 @@ export class ZabbixVariableQueryEditor extends PureComponent<VariableQueryProps,
|
||||
this.props.onChange(queryModel, `Zabbix - ${queryType}`);
|
||||
};
|
||||
|
||||
render() {
|
||||
async render() {
|
||||
const { selectedQueryType, legacyQuery, group, host, application, itemTag, item } = this.state;
|
||||
const { datasource } = this.props;
|
||||
const supportsItemTags = datasource?.zabbix?.isZabbix54OrHigher() || false;
|
||||
const supportsItemTags = (await datasource?.zabbix?.isZabbix54OrHigher()) || false;
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -41,7 +41,7 @@ export function expandItemName(name: string, key: string): string {
|
||||
return name;
|
||||
}
|
||||
|
||||
export function expandItems(items) {
|
||||
export function expandItems(items: any[]) {
|
||||
_.forEach(items, (item) => {
|
||||
item.item = item.name;
|
||||
item.name = expandItemName(item.item, item.key_);
|
||||
|
||||
@@ -88,6 +88,10 @@ export class ZabbixAPIConnector {
|
||||
}
|
||||
|
||||
initVersion(): Promise<string> {
|
||||
if (this.version) {
|
||||
return Promise.resolve(this.version);
|
||||
}
|
||||
|
||||
if (!this.getVersionPromise) {
|
||||
this.getVersionPromise = Promise.resolve(
|
||||
this.getVersion().then((version) => {
|
||||
@@ -142,7 +146,7 @@ export class ZabbixAPIConnector {
|
||||
return this.request('hostgroup.get', params);
|
||||
}
|
||||
|
||||
getHosts(groupids) {
|
||||
getHosts(groupids): Promise<any[]> {
|
||||
const params: any = {
|
||||
output: ['hostid', 'name', 'host'],
|
||||
sortfield: 'name',
|
||||
@@ -174,7 +178,7 @@ export class ZabbixAPIConnector {
|
||||
* @param {String} itemtype 'num' or 'text'
|
||||
* @return {[type]} array of items
|
||||
*/
|
||||
getItems(hostids, appids, itemtype) {
|
||||
getItems(hostids, appids, itemtype, itemTagFilter?: string): Promise<any[]> {
|
||||
const params: any = {
|
||||
output: ['itemid', 'name', 'key_', 'value_type', 'hostid', 'status', 'state', 'units', 'valuemapid', 'delay'],
|
||||
sortfield: 'name',
|
||||
@@ -199,6 +203,18 @@ export class ZabbixAPIConnector {
|
||||
|
||||
if (this.isZabbix54OrHigher()) {
|
||||
params.selectTags = 'extend';
|
||||
if (itemTagFilter) {
|
||||
const allTags = itemTagFilter.split(',');
|
||||
let tagsParam = [];
|
||||
const regex = /.*?([a-zA-Z0-9\s\-_]*):\s*([a-zA-Z0-9\-_\/:]*)/;
|
||||
for (let i = 0; i < allTags.length; i++) {
|
||||
const matches = allTags[i].match(regex);
|
||||
tagsParam.push({ tag: matches[1].replace('/', ''), value: matches[2].trim(), operator: '1' });
|
||||
}
|
||||
params.tags = tagsParam;
|
||||
// Use OR eval type
|
||||
params.evaltype = 2;
|
||||
}
|
||||
}
|
||||
|
||||
return this.request('item.get', params).then(utils.expandItems);
|
||||
|
||||
@@ -252,8 +252,8 @@ export class Zabbix implements ZabbixConnector {
|
||||
return version ? semver.gte(version, '6.0.0') : true;
|
||||
}
|
||||
|
||||
isZabbix54OrHigher() {
|
||||
const version = this.version || this.zabbixAPI.version;
|
||||
async isZabbix54OrHigher() {
|
||||
const version = await this.zabbixAPI.initVersion();
|
||||
return version ? semver.gte(version, '5.4.0') : false;
|
||||
}
|
||||
|
||||
@@ -301,28 +301,28 @@ export class Zabbix implements ZabbixConnector {
|
||||
return this.zabbixAPI.getGroups();
|
||||
}
|
||||
|
||||
getGroups(groupFilter) {
|
||||
getGroups(groupFilter): Promise<any[]> {
|
||||
return this.getAllGroups().then((groups) => findByFilter(groups, groupFilter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of host belonging to given groups.
|
||||
*/
|
||||
getAllHosts(groupFilter) {
|
||||
getAllHosts(groupFilter): Promise<any[]> {
|
||||
return this.getGroups(groupFilter).then((groups) => {
|
||||
const groupids = _.map(groups, 'groupid');
|
||||
return this.zabbixAPI.getHosts(groupids);
|
||||
});
|
||||
}
|
||||
|
||||
getHosts(groupFilter?, hostFilter?) {
|
||||
getHosts(groupFilter?, hostFilter?): Promise<any[]> {
|
||||
return this.getAllHosts(groupFilter).then((hosts) => findByFilter(hosts, hostFilter));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of applications belonging to given groups and hosts.
|
||||
*/
|
||||
async getAllApps(groupFilter, hostFilter) {
|
||||
async getAllApps(groupFilter, hostFilter): Promise<any[]> {
|
||||
await this.getVersion();
|
||||
if (!this.supportsApplications()) {
|
||||
return [];
|
||||
@@ -378,22 +378,44 @@ export class Zabbix implements ZabbixConnector {
|
||||
return findByFilter(tagsStr, itemTagFilter);
|
||||
}
|
||||
|
||||
async getAllItems(groupFilter, hostFilter, appFilter, itemTagFilter, options: any = {}) {
|
||||
async getAllItems(
|
||||
groupFilter: string,
|
||||
hostFilter: string,
|
||||
appFilter: string,
|
||||
itemTagFilter: string,
|
||||
options: any = {}
|
||||
): Promise<any[]> {
|
||||
if (!this.isZabbix54OrHigher()) {
|
||||
return this.getAllItemsBefore54(groupFilter, hostFilter, appFilter, itemTagFilter, options);
|
||||
}
|
||||
|
||||
const hosts = await this.getHosts(groupFilter, hostFilter);
|
||||
const hostids = _.map(hosts, 'hostid');
|
||||
|
||||
// Support regexp in tags
|
||||
if (utils.isRegex(itemTagFilter)) {
|
||||
const tags = await this.getItemTags(groupFilter, hostFilter, itemTagFilter);
|
||||
itemTagFilter = tags.map((t) => t.name).join(',');
|
||||
}
|
||||
|
||||
let items = await this.zabbixAPI.getItems(hostids, undefined, options.itemtype, itemTagFilter);
|
||||
|
||||
if (!options.showDisabledItems) {
|
||||
items = _.filter(items, { status: '0' });
|
||||
}
|
||||
|
||||
return await this.expandUserMacro(items, false);
|
||||
}
|
||||
|
||||
async getAllItemsBefore54(groupFilter, hostFilter, appFilter, itemTagFilter, options: any = {}) {
|
||||
const apps = await this.getApps(groupFilter, hostFilter, appFilter);
|
||||
let items: any[];
|
||||
|
||||
if (this.isZabbix54OrHigher()) {
|
||||
items = await this.zabbixAPI.getItems(apps.hostids, undefined, options.itemtype);
|
||||
if (itemTagFilter) {
|
||||
items = filterItemsByTag(items, itemTagFilter);
|
||||
}
|
||||
if (apps.appFilterEmpty) {
|
||||
items = await this.zabbixAPI.getItems(apps.hostids, undefined, options.itemtype, undefined);
|
||||
} else {
|
||||
if (apps.appFilterEmpty) {
|
||||
items = await this.zabbixAPI.getItems(apps.hostids, undefined, options.itemtype);
|
||||
} else {
|
||||
const appids = _.map(apps, 'applicationid');
|
||||
items = await this.zabbixAPI.getItems(undefined, appids, options.itemtype);
|
||||
}
|
||||
const appids = _.map(apps, 'applicationid');
|
||||
items = await this.zabbixAPI.getItems(undefined, appids, options.itemtype, undefined);
|
||||
}
|
||||
|
||||
if (!options.showDisabledItems) {
|
||||
@@ -746,28 +768,3 @@ function getHostIds(items) {
|
||||
});
|
||||
return _.uniq(_.flatten(hostIds));
|
||||
}
|
||||
|
||||
function filterItemsByTag(items: any[], itemTagFilter: string) {
|
||||
if (utils.isRegex(itemTagFilter)) {
|
||||
const filterPattern = utils.buildRegex(itemTagFilter);
|
||||
return items.filter((item) => {
|
||||
if (item.tags) {
|
||||
const tags: string[] = item.tags.map((t) => utils.itemTagToString(t));
|
||||
return tags.some((tag) => {
|
||||
return filterPattern.test(tag);
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return items.filter((item) => {
|
||||
if (item.tags) {
|
||||
const tags: string[] = item.tags.map((t) => utils.itemTagToString(t));
|
||||
return tags.includes(itemTagFilter);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user