diff --git a/src/datasource/responseHandler.ts b/src/datasource/responseHandler.ts index 0682f61..d7363ed 100644 --- a/src/datasource/responseHandler.ts +++ b/src/datasource/responseHandler.ts @@ -540,6 +540,74 @@ export function handleSLIResponse(response: any, itservices: any[], target: Zabb }); } +export function handleMultiSLIResponse(response: any[], itservices: any[], slas: any[], target: ZabbixMetricsQuery) { + if (!response || response?.length === 0) { + return new MutableDataFrame({ + refId: target.refId, + name: 'SLI', + fields: [], + }); + } + + const firstResponse = response[0]; + const timestamps = []; + for (let i = 0; i < firstResponse?.periods?.length; i++) { + const period = firstResponse.periods[i]; + timestamps.push(period.period_from * 1000); + } + + const timeFiled: Field = { + name: TIME_SERIES_TIME_FIELD_NAME, + type: FieldType.time, + config: { + custom: {}, + }, + values: new ArrayVector(timestamps), + }; + + const valueFields: Field[] = []; + const slaProperty = mapLegacySLAProperty(target.slaProperty); + + for (let respIdx = 0; respIdx < response.length; respIdx++) { + const res = response[respIdx]; + const values: number[][] = []; + for (let i = 0; i < res?.sli?.length; i++) { + const slis = res.sli[i]; + for (let j = 0; j < slis.length; j++) { + const sli = slis[j]; + const value = sli[slaProperty]; + if (!values[j]) { + values[j] = []; + } + values[j].push(value); + } + } + + for (let i = 0; i < res?.serviceids?.length; i++) { + const serviceId = res?.serviceids[i].toString(); + const service = itservices.find((s) => s.serviceid === serviceId); + let name = `${service?.name || serviceId}`; + if (response.length > 1) { + const sla = slas[respIdx]; + name = `${name}: ${sla.name}`; + } + + valueFields.push({ + name, + type: FieldType.number, + config: {}, + values: new ArrayVector(values[i]), + }); + } + } + + return new MutableDataFrame({ + refId: target.refId, + name: 'SLI', + fields: [timeFiled, ...valueFields], + }); +} + function mapLegacySLAProperty(property: string) { switch (property) { case 'sla': diff --git a/src/datasource/zabbix/zabbix.ts b/src/datasource/zabbix/zabbix.ts index d085527..c902f2f 100644 --- a/src/datasource/zabbix/zabbix.ts +++ b/src/datasource/zabbix/zabbix.ts @@ -3,7 +3,7 @@ import _ from 'lodash'; import moment from 'moment'; import semver from 'semver'; import * as utils from '../utils'; -import responseHandler, { handleServiceResponse, handleSLIResponse } from '../responseHandler'; +import responseHandler, { handleMultiSLIResponse, handleServiceResponse, handleSLIResponse } from '../responseHandler'; import { CachingProxy } from './proxy/cachingProxy'; import { DBConnector } from './connectors/dbConnector'; import { ZabbixAPIConnector } from './connectors/zabbix_api/zabbixAPIConnector'; @@ -667,9 +667,15 @@ export class Zabbix implements ZabbixConnector { } const slaIds = slas.map((s) => s.slaid); - const slaId = slaIds?.length > 0 ? slaIds[0] : undefined; - const result = await this.zabbixAPI.getSLI(slaId, itServiceIds, timeRange, options); - return handleSLIResponse(result, itservices, target); + if (slaIds.length > 1) { + const sliQueries = slaIds?.map((slaId) => this.zabbixAPI.getSLI(slaId, itServiceIds, timeRange, options)); + const results = await Promise.all(sliQueries); + return handleMultiSLIResponse(results, itservices, slas, target); + } else { + const slaId = slaIds?.length > 0 ? slaIds[0] : undefined; + const result = await this.zabbixAPI.getSLI(slaId, itServiceIds, timeRange, options); + return handleSLIResponse(result, itservices, target); + } } async getSLA(itservices, timeRange, target, options) {