diff --git a/src/datasource-zabbix/constants.ts b/src/datasource-zabbix/constants.ts index 164168f..e107087 100644 --- a/src/datasource-zabbix/constants.ts +++ b/src/datasource-zabbix/constants.ts @@ -34,12 +34,12 @@ export const ZBX_ACK_ACTION_ADD_MESSAGE = 4; export const ZBX_ACK_ACTION_CHANGE_SEVERITY = 8; export const TRIGGER_SEVERITY = [ - {val: 0, text: 'Not classified'}, - {val: 1, text: 'Information'}, - {val: 2, text: 'Warning'}, - {val: 3, text: 'Average'}, - {val: 4, text: 'High'}, - {val: 5, text: 'Disaster'} + { val: 0, text: 'Not classified' }, + { val: 1, text: 'Information' }, + { val: 2, text: 'Warning' }, + { val: 3, text: 'Average' }, + { val: 4, text: 'High' }, + { val: 5, text: 'Disaster' }, ]; /** Minimum interval for SLA over time (1 hour) */ diff --git a/src/datasource-zabbix/dataProcessor.ts b/src/datasource-zabbix/dataProcessor.ts index 5c1e8e8..fd86073 100644 --- a/src/datasource-zabbix/dataProcessor.ts +++ b/src/datasource-zabbix/dataProcessor.ts @@ -5,7 +5,7 @@ import { DataFrame, FieldType, TIME_SERIES_VALUE_FIELD_NAME } from '@grafana/dat function setAlias(alias: string, frame: DataFrame) { if (frame.fields?.length <= 2) { - const valueField = frame.fields.find(f => f.name === TIME_SERIES_VALUE_FIELD_NAME); + const valueField = frame.fields.find((f) => f.name === TIME_SERIES_VALUE_FIELD_NAME); if (valueField?.config?.custom?.scopedVars) { alias = getTemplateSrv().replace(alias, valueField?.config?.custom?.scopedVars); } @@ -38,7 +38,7 @@ function replaceAlias(regexp: string, newAlias: string, frame: DataFrame) { if (frame.fields?.length <= 2) { let alias = frame.name.replace(pattern, newAlias); - const valueField = frame.fields.find(f => f.name === TIME_SERIES_VALUE_FIELD_NAME); + const valueField = frame.fields.find((f) => f.name === TIME_SERIES_VALUE_FIELD_NAME); if (valueField?.state?.scopedVars) { alias = getTemplateSrv().replace(alias, valueField?.state?.scopedVars); } @@ -63,7 +63,7 @@ function replaceAlias(regexp: string, newAlias: string, frame: DataFrame) { function setAliasByRegex(alias: string, frame: DataFrame) { if (frame.fields?.length <= 2) { - const valueField = frame.fields.find(f => f.name === TIME_SERIES_VALUE_FIELD_NAME); + const valueField = frame.fields.find((f) => f.name === TIME_SERIES_VALUE_FIELD_NAME); try { if (valueField) { valueField.config.displayNameFromDS = extractText(valueField.config?.displayNameFromDS, alias); @@ -96,7 +96,7 @@ function extractText(str: string, pattern: string) { function timeShift(interval, range) { const shift = utils.parseTimeShiftInterval(interval) / 1000; - return _.map(range, time => { + return _.map(range, (time) => { return time - shift; }); } @@ -105,11 +105,11 @@ const metricFunctions = { timeShift: timeShift, setAlias: setAlias, setAliasByRegex: setAliasByRegex, - replaceAlias: replaceAlias + replaceAlias: replaceAlias, }; export default { get metricFunctions() { return metricFunctions; - } + }, }; diff --git a/src/datasource-zabbix/problemsHandler.ts b/src/datasource-zabbix/problemsHandler.ts index 7f4c44e..b7c02fa 100644 --- a/src/datasource-zabbix/problemsHandler.ts +++ b/src/datasource-zabbix/problemsHandler.ts @@ -41,7 +41,6 @@ export function joinTriggersWithProblems(problems: ZBXProblem[], triggers: ZBXTr problemDTOList.push(problemDTO); } - } return problemDTOList; @@ -51,7 +50,11 @@ interface JoinOptions { valueFromEvent?: boolean; } -export function joinTriggersWithEvents(events: ZBXEvent[], triggers: ZBXTrigger[], options?: JoinOptions): ProblemDTO[] { +export function joinTriggersWithEvents( + events: ZBXEvent[], + triggers: ZBXTrigger[], + options?: JoinOptions +): ProblemDTO[] { const { valueFromEvent } = options; const problemDTOList: ProblemDTO[] = []; @@ -89,7 +92,6 @@ export function joinTriggersWithEvents(events: ZBXEvent[], triggers: ZBXTrigger[ problemDTOList.push(problemDTO); } - } return problemDTOList; @@ -118,7 +120,7 @@ export function addTriggerDataSource(triggers, target) { } export function addTriggerHostProxy(triggers, proxies) { - triggers.forEach(trigger => { + triggers.forEach((trigger) => { if (trigger.hosts && trigger.hosts.length) { const host = trigger.hosts[0]; if (host.proxy_hostid !== '0') { @@ -147,11 +149,11 @@ export function filterTriggersPre(triggerList, replacedTarget) { function filterTriggers(triggers, triggerFilter) { if (utils.isRegex(triggerFilter)) { - return _.filter(triggers, trigger => { + return _.filter(triggers, (trigger) => { return utils.buildRegex(triggerFilter).test(trigger.description); }); } else { - return _.filter(triggers, trigger => { + return _.filter(triggers, (trigger) => { return trigger.description === triggerFilter; }); } diff --git a/src/datasource-zabbix/timeseries.ts b/src/datasource-zabbix/timeseries.ts index 3a77ee4..deaf5c7 100644 --- a/src/datasource-zabbix/timeseries.ts +++ b/src/datasource-zabbix/timeseries.ts @@ -26,7 +26,7 @@ function downsample(datapoints, time_to, ms_interval, func) { const downsampledSeries = []; const timeWindow = { from: time_to * 1000 - ms_interval, - to: time_to * 1000 + to: time_to * 1000, }; let points_sum = 0; @@ -42,9 +42,9 @@ function downsample(datapoints, time_to, ms_interval, func) { } else { value_avg = points_num ? points_sum / points_num : 0; - if (func === "max") { + if (func === 'max') { downsampledSeries.push([_.max(frame), timeWindow.to]); - } else if (func === "min") { + } else if (func === 'min') { downsampledSeries.push([_.min(frame), timeWindow.to]); } else { downsampledSeries.push([value_avg, timeWindow.to]); @@ -156,24 +156,26 @@ function groupBy(datapoints, interval, groupByCallback) { const ms_interval = utils.parseInterval(interval); // Calculate frame timestamps - const frames = _.groupBy(datapoints, point => { + const frames = _.groupBy(datapoints, (point) => { // Calculate time for group of points return Math.floor(point[1] / ms_interval) * ms_interval; }); // frame: { '': [[, ], ...] } // return [{ '': }, { '': }, ...] - const grouped = _.mapValues(frames, frame => { - const points = _.map(frame, point => { + const grouped = _.mapValues(frames, (frame) => { + const points = _.map(frame, (point) => { return point[0]; }); return groupByCallback(points); }); // Convert points to Grafana format - return sortByTime(_.map(grouped, (value, timestamp) => { - return [Number(value), Number(timestamp)]; - })); + return sortByTime( + _.map(grouped, (value, timestamp) => { + return [Number(value), Number(timestamp)]; + }) + ); } export function groupBy_perf(datapoints, interval, groupByCallback) { @@ -228,7 +230,10 @@ export function groupByRange(datapoints, groupByCallback) { frame_values.push(point[POINT_VALUE]); } const frame_value = groupByCallback(frame_values); - return [[frame_value, frame_start], [frame_value, frame_end]]; + return [ + [frame_value, frame_start], + [frame_value, frame_end], + ]; } /** @@ -236,19 +241,20 @@ export function groupByRange(datapoints, groupByCallback) { * @param {datapoints[]} timeseries array of time series */ function sumSeries(timeseries) { - // Calculate new points for interpolation - let new_timestamps = _.uniq(_.map(_.flatten(timeseries), point => { - return point[1]; - })); + let new_timestamps = _.uniq( + _.map(_.flatten(timeseries), (point) => { + return point[1]; + }) + ); new_timestamps = _.sortBy(new_timestamps); - const interpolated_timeseries = _.map(timeseries, series => { + const interpolated_timeseries = _.map(timeseries, (series) => { series = fillZeroes(series, new_timestamps); - const timestamps = _.map(series, point => { + const timestamps = _.map(series, (point) => { return point[1]; }); - const new_points = _.map(_.difference(new_timestamps, timestamps), timestamp => { + const new_points = _.map(_.difference(new_timestamps, timestamps), (timestamp) => { return [null, timestamp]; }); const new_series = series.concat(new_points); @@ -271,20 +277,14 @@ function sumSeries(timeseries) { } function scale(datapoints, factor) { - return _.map(datapoints, point => { - return [ - point[0] * factor, - point[1] - ]; + return _.map(datapoints, (point) => { + return [point[0] * factor, point[1]]; }); } function scale_perf(datapoints, factor) { for (let i = 0; i < datapoints.length; i++) { - datapoints[i] = [ - datapoints[i][POINT_VALUE] * factor, - datapoints[i][POINT_TIMESTAMP] - ]; + datapoints[i] = [datapoints[i][POINT_VALUE] * factor, datapoints[i][POINT_TIMESTAMP]]; } return datapoints; @@ -292,10 +292,7 @@ function scale_perf(datapoints, factor) { function offset(datapoints, delta) { for (let i = 0; i < datapoints.length; i++) { - datapoints[i] = [ - datapoints[i][POINT_VALUE] + delta, - datapoints[i][POINT_TIMESTAMP] - ]; + datapoints[i] = [datapoints[i][POINT_VALUE] + delta, datapoints[i][POINT_TIMESTAMP]]; } return datapoints; @@ -440,7 +437,7 @@ function expMovingAverage(datapoints: TimeSeriesPoints, n: number): TimeSeriesPo function PERCENTILE(n, values) { const sorted = _.sortBy(values); - return sorted[Math.floor(sorted.length * n / 100)]; + return sorted[Math.floor((sorted.length * n) / 100)]; } function COUNT(values) { @@ -505,7 +502,7 @@ function getPointTimeFrame(timestamp, ms_interval) { } function sortByTime(series) { - return _.sortBy(series, point => { + return _.sortBy(series, (point) => { return point[1]; }); } @@ -561,7 +558,7 @@ function linearInterpolation(timestamp, left, right) { if (left[1] === right[1]) { return (left[0] + right[0]) / 2; } else { - return (left[0] + (right[0] - left[0]) / (right[1] - left[1]) * (timestamp - left[1])); + return left[0] + ((right[0] - left[0]) / (right[1] - left[1])) * (timestamp - left[1]); } } diff --git a/src/datasource-zabbix/zabbix/connectors/dbConnector.ts b/src/datasource-zabbix/zabbix/connectors/dbConnector.ts index 74ecd36..6b3f23c 100644 --- a/src/datasource-zabbix/zabbix/connectors/dbConnector.ts +++ b/src/datasource-zabbix/zabbix/connectors/dbConnector.ts @@ -8,27 +8,27 @@ export const HISTORY_TO_TABLE_MAP = { '1': 'history_str', '2': 'history_log', '3': 'history_uint', - '4': 'history_text' + '4': 'history_text', }; export const TREND_TO_TABLE_MAP = { '0': 'trends', - '3': 'trends_uint' + '3': 'trends_uint', }; export const consolidateByFunc = { - 'avg': 'AVG', - 'min': 'MIN', - 'max': 'MAX', - 'sum': 'SUM', - 'count': 'COUNT' + avg: 'AVG', + min: 'MIN', + max: 'MAX', + sum: 'SUM', + count: 'COUNT', }; export const consolidateByTrendColumns = { - 'avg': 'value_avg', - 'min': 'value_min', - 'max': 'value_max', - 'sum': 'num*value_avg' // sum of sums inside the one-hour trend period + avg: 'value_avg', + min: 'value_min', + max: 'value_max', + sum: 'num*value_avg', // sum of sums inside the one-hour trend period }; export interface IDBConnector { @@ -58,7 +58,7 @@ export class DBConnector { static loadDatasource(dsId, dsName) { if (!dsName && dsId !== undefined) { - const ds = _.find(getDataSourceSrv().getList(), { 'id': dsId }); + const ds = _.find(getDataSourceSrv().getList(), { id: dsId }); if (!ds) { return Promise.reject(`Data Source with ID ${dsId} not found`); } @@ -72,8 +72,7 @@ export class DBConnector { } loadDBDataSource() { - return DBConnector.loadDatasource(this.datasourceId, this.datasourceName) - .then(ds => { + return DBConnector.loadDatasource(this.datasourceId, this.datasourceName).then((ds) => { this.datasourceTypeId = ds.meta.id; this.datasourceTypeName = ds.meta.name; if (!this.datasourceName) { @@ -93,5 +92,5 @@ export default { HISTORY_TO_TABLE_MAP, TREND_TO_TABLE_MAP, consolidateByFunc, - consolidateByTrendColumns + consolidateByTrendColumns, }; diff --git a/src/datasource-zabbix/zabbix/connectors/influxdb/influxdbConnector.ts b/src/datasource-zabbix/zabbix/connectors/influxdb/influxdbConnector.ts index 296fe4f..92ec0c4 100644 --- a/src/datasource-zabbix/zabbix/connectors/influxdb/influxdbConnector.ts +++ b/src/datasource-zabbix/zabbix/connectors/influxdb/influxdbConnector.ts @@ -1,14 +1,24 @@ -import { ArrayVector, DataFrame, dataFrameToJSON, DataSourceApi, Field, FieldType, MutableDataFrame, TIME_SERIES_TIME_FIELD_NAME, toDataFrame } from '@grafana/data'; +import { + ArrayVector, + DataFrame, + dataFrameToJSON, + DataSourceApi, + Field, + FieldType, + MutableDataFrame, + TIME_SERIES_TIME_FIELD_NAME, + toDataFrame, +} from '@grafana/data'; import _ from 'lodash'; import { compactQuery } from '../../../utils'; import { consolidateByTrendColumns, DBConnector, HISTORY_TO_TABLE_MAP } from '../dbConnector'; const consolidateByFunc = { - 'avg': 'MEAN', - 'min': 'MIN', - 'max': 'MAX', - 'sum': 'SUM', - 'count': 'COUNT' + avg: 'MEAN', + min: 'MIN', + max: 'MAX', + sum: 'SUM', + count: 'COUNT', }; export class InfluxDBConnector extends DBConnector { @@ -18,7 +28,7 @@ export class InfluxDBConnector extends DBConnector { constructor(options) { super(options); this.retentionPolicy = options.retentionPolicy; - super.loadDBDataSource().then(ds => { + super.loadDBDataSource().then((ds) => { this.influxDS = ds; return ds; }); @@ -28,12 +38,12 @@ export class InfluxDBConnector extends DBConnector { * Try to invoke test query for one of Zabbix database tables. */ testDataSource() { - return this.influxDS.testDatasource().then(result => { + return this.influxDS.testDatasource().then((result) => { if (result.status && result.status === 'error') { return Promise.reject({ data: { - message: `InfluxDB connection error: ${result.message}` - } + message: `InfluxDB connection error: ${result.message}`, + }, }); } return result; @@ -58,10 +68,10 @@ export class InfluxDBConnector extends DBConnector { }); return Promise.all(promises) - .then(_.flatten) - .then(results => { - return handleInfluxHistoryResponse(results); - }); + .then(_.flatten) + .then((results) => { + return handleInfluxHistoryResponse(results); + }); } getTrends(items, timeFrom, timeTill, options) { @@ -88,7 +98,7 @@ export class InfluxDBConnector extends DBConnector { } buildWhereClause(itemids) { - const itemidsWhere = itemids.map(itemid => `"itemid" = '${itemid}'`).join(' OR '); + const itemidsWhere = itemids.map((itemid) => `"itemid" = '${itemid}'`).join(' OR '); return `(${itemidsWhere})`; } @@ -127,7 +137,7 @@ function handleInfluxHistoryResponse(results) { if (influxSeries.values) { for (i = 0; i < influxSeries.values.length; i++) { tsBuffer.push(influxSeries.values[i][0]); - valuesBuffer.push(influxSeries.values[i][1]) + valuesBuffer.push(influxSeries.values[i][1]); } } const timeFiled: Field = { @@ -144,12 +154,14 @@ function handleInfluxHistoryResponse(results) { values: new ArrayVector(valuesBuffer), }; - frames.push(new MutableDataFrame({ - name: influxSeries?.tags?.itemid, - fields: [timeFiled, valueFiled] - })); + frames.push( + new MutableDataFrame({ + name: influxSeries?.tags?.itemid, + fields: [timeFiled, valueFiled], + }) + ); } } - return frames.map(f => dataFrameToJSON(f)); + return frames.map((f) => dataFrameToJSON(f)); } diff --git a/src/datasource-zabbix/zabbix/connectors/sql/mysql.ts b/src/datasource-zabbix/zabbix/connectors/sql/mysql.ts index 167ea94..f43272d 100644 --- a/src/datasource-zabbix/zabbix/connectors/sql/mysql.ts +++ b/src/datasource-zabbix/zabbix/connectors/sql/mysql.ts @@ -40,7 +40,7 @@ function testQuery() { const mysql = { historyQuery, trendsQuery, - testQuery + testQuery, }; export default mysql; diff --git a/src/datasource-zabbix/zabbix/connectors/sql/postgres.ts b/src/datasource-zabbix/zabbix/connectors/sql/postgres.ts index fcece78..d79743e 100644 --- a/src/datasource-zabbix/zabbix/connectors/sql/postgres.ts +++ b/src/datasource-zabbix/zabbix/connectors/sql/postgres.ts @@ -46,7 +46,7 @@ function testQuery() { const postgres = { historyQuery, trendsQuery, - testQuery + testQuery, }; export default postgres; diff --git a/src/datasource-zabbix/zabbix/connectors/sql/sqlConnector.ts b/src/datasource-zabbix/zabbix/connectors/sql/sqlConnector.ts index c2e7657..b375c38 100644 --- a/src/datasource-zabbix/zabbix/connectors/sql/sqlConnector.ts +++ b/src/datasource-zabbix/zabbix/connectors/sql/sqlConnector.ts @@ -3,11 +3,16 @@ import { getBackendSrv } from '@grafana/runtime'; import { compactQuery } from '../../../utils'; import mysql from './mysql'; import postgres from './postgres'; -import dbConnector, { DBConnector, DEFAULT_QUERY_LIMIT, HISTORY_TO_TABLE_MAP, TREND_TO_TABLE_MAP } from '../dbConnector'; +import dbConnector, { + DBConnector, + DEFAULT_QUERY_LIMIT, + HISTORY_TO_TABLE_MAP, + TREND_TO_TABLE_MAP, +} from '../dbConnector'; const supportedDatabases = { mysql: 'mysql', - postgres: 'postgres' + postgres: 'postgres', }; export class SQLConnector extends DBConnector { @@ -20,8 +25,7 @@ export class SQLConnector extends DBConnector { this.limit = options.limit || DEFAULT_QUERY_LIMIT; this.sqlDialect = null; - super.loadDBDataSource() - .then(() => { + super.loadDBDataSource().then(() => { this.loadSQLDialect(); }); } @@ -56,7 +60,7 @@ export class SQLConnector extends DBConnector { return this.invokeSQLQuery(query); }); - return Promise.all(promises).then(results => { + return Promise.all(promises).then((results) => { return _.flatten(results); }); } @@ -72,13 +76,21 @@ export class SQLConnector extends DBConnector { const table = TREND_TO_TABLE_MAP[value_type]; let valueColumn = _.includes(['avg', 'min', 'max', 'sum'], consolidateBy) ? consolidateBy : 'avg'; valueColumn = dbConnector.consolidateByTrendColumns[valueColumn]; - let query = this.sqlDialect.trendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn); + let query = this.sqlDialect.trendsQuery( + itemids, + table, + timeFrom, + timeTill, + intervalSec, + aggFunction, + valueColumn + ); query = compactQuery(query); return this.invokeSQLQuery(query); }); - return Promise.all(promises).then(results => { + return Promise.all(promises).then((results) => { return _.flatten(results); }); } @@ -89,24 +101,25 @@ export class SQLConnector extends DBConnector { format: 'time_series', datasourceId: this.datasourceId, rawSql: query, - maxDataPoints: this.limit + maxDataPoints: this.limit, }; - return getBackendSrv().datasourceRequest({ - url: '/api/ds/query', - method: 'POST', - data: { - queries: [queryDef], - } - }) - .then(response => { - const results = response.data.results; - if (results['A']) { - return results['A'].frames; - } else { - return null; - } - }); + return getBackendSrv() + .datasourceRequest({ + url: '/api/ds/query', + method: 'POST', + data: { + queries: [queryDef], + }, + }) + .then((response) => { + const results = response.data.results; + if (results['A']) { + return results['A'].frames; + } else { + return null; + } + }); } } diff --git a/src/datasource-zabbix/zabbix/proxy/cachingProxy.ts b/src/datasource-zabbix/zabbix/proxy/cachingProxy.ts index 7a7eca4..9d45b28 100644 --- a/src/datasource-zabbix/zabbix/proxy/cachingProxy.ts +++ b/src/datasource-zabbix/zabbix/proxy/cachingProxy.ts @@ -11,7 +11,7 @@ export class CachingProxy { constructor(cacheOptions) { this.cacheEnabled = cacheOptions.enabled; - this.ttl = cacheOptions.ttl || 600000; // 10 minutes by default + this.ttl = cacheOptions.ttl || 600000; // 10 minutes by default // Internal objects for data storing this.cache = {}; @@ -57,18 +57,20 @@ export class CachingProxy { */ function callOnce(func, promiseKeeper, funcScope) { // tslint:disable-next-line: only-arrow-functions - return function() { + return function () { const hash = getRequestHash(arguments); if (!promiseKeeper[hash]) { promiseKeeper[hash] = Promise.resolve( - func.apply(funcScope, arguments) - .then(result => { - promiseKeeper[hash] = null; - return result; - }).catch(err => { - promiseKeeper[hash] = null; - throw err; - }) + func + .apply(funcScope, arguments) + .then((result) => { + promiseKeeper[hash] = null; + return result; + }) + .catch((err) => { + promiseKeeper[hash] = null; + throw err; + }) ); } return promiseKeeper[hash]; @@ -77,7 +79,7 @@ function callOnce(func, promiseKeeper, funcScope) { function cacheRequest(func, funcName, funcScope, self) { // tslint:disable-next-line: only-arrow-functions - return function() { + return function () { if (!self.cache[funcName]) { self.cache[funcName] = {}; } @@ -87,12 +89,11 @@ function cacheRequest(func, funcName, funcScope, self) { if (self.cacheEnabled && !self._isExpired(cacheObject[hash])) { return Promise.resolve(cacheObject[hash].value); } else { - return func.apply(funcScope, arguments) - .then(result => { + return func.apply(funcScope, arguments).then((result) => { if (result !== undefined) { cacheObject[hash] = { value: result, - timestamp: Date.now() + timestamp: Date.now(), }; } return result; @@ -107,11 +108,14 @@ function getRequestHash(args) { } function getHash(str: string): number { - let hash = 0, i, chr, len; + let hash = 0, + i, + chr, + len; if (str.length !== 0) { for (i = 0, len = str.length; i < len; i++) { - chr = str.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; + chr = str.charCodeAt(i); + hash = (hash << 5) - hash + chr; hash |= 0; // Convert to 32bit integer } } diff --git a/src/datasource-zabbix/zabbix/zabbix.ts b/src/datasource-zabbix/zabbix/zabbix.ts index 48af066..40537dc 100644 --- a/src/datasource-zabbix/zabbix/zabbix.ts +++ b/src/datasource-zabbix/zabbix/zabbix.ts @@ -18,19 +18,59 @@ interface AppsResponse extends Array { } const REQUESTS_TO_PROXYFY = [ - 'getHistory', 'getTrend', 'getGroups', 'getHosts', 'getApps', 'getItems', 'getMacros', 'getItemsByIDs', - 'getEvents', 'getAlerts', 'getHostAlerts', 'getAcknowledges', 'getITService', 'getSLA', 'getProxies', - 'getEventAlerts', 'getExtendedEventData', 'getProblems', 'getEventsHistory', 'getTriggersByIds', 'getScripts', 'getValueMappings' + 'getHistory', + 'getTrend', + 'getGroups', + 'getHosts', + 'getApps', + 'getItems', + 'getMacros', + 'getItemsByIDs', + 'getEvents', + 'getAlerts', + 'getHostAlerts', + 'getAcknowledges', + 'getITService', + 'getSLA', + 'getProxies', + 'getEventAlerts', + 'getExtendedEventData', + 'getProblems', + 'getEventsHistory', + 'getTriggersByIds', + 'getScripts', + 'getValueMappings', ]; const REQUESTS_TO_CACHE = [ - 'getGroups', 'getHosts', 'getApps', 'getItems', 'getMacros', 'getItemsByIDs', 'getITService', 'getProxies', 'getValueMappings' + 'getGroups', + 'getHosts', + 'getApps', + 'getItems', + 'getMacros', + 'getItemsByIDs', + 'getITService', + 'getProxies', + 'getValueMappings', ]; const REQUESTS_TO_BIND = [ - 'getHistory', 'getTrend', 'getMacros', 'getItemsByIDs', 'getEvents', 'getAlerts', 'getHostAlerts', - 'getAcknowledges', 'getITService', 'acknowledgeEvent', 'getProxies', 'getEventAlerts', - 'getExtendedEventData', 'getScripts', 'executeScript', 'getValueMappings' + 'getHistory', + 'getTrend', + 'getMacros', + 'getItemsByIDs', + 'getEvents', + 'getAlerts', + 'getHostAlerts', + 'getAcknowledges', + 'getITService', + 'acknowledgeEvent', + 'getProxies', + 'getEventAlerts', + 'getExtendedEventData', + 'getScripts', + 'executeScript', + 'getValueMappings', ]; export class Zabbix implements ZabbixConnector { @@ -74,7 +114,7 @@ export class Zabbix implements ZabbixConnector { // Initialize caching proxy for requests const cacheOptions = { enabled: true, - ttl: cacheTTL + ttl: cacheTTL, }; this.cachingProxy = new CachingProxy(cacheOptions); @@ -86,17 +126,23 @@ export class Zabbix implements ZabbixConnector { if (enableDirectDBConnection) { const connectorOptions: any = { dbConnectionRetentionPolicy }; - this.initDBConnector(dbConnectionDatasourceId, dbConnectionDatasourceName, connectorOptions) - .then(() => { - this.getHistoryDB = this.cachingProxy.proxifyWithCache(this.dbConnector.getHistory, 'getHistory', this.dbConnector); - this.getTrendsDB = this.cachingProxy.proxifyWithCache(this.dbConnector.getTrends, 'getTrends', this.dbConnector); + this.initDBConnector(dbConnectionDatasourceId, dbConnectionDatasourceName, connectorOptions).then(() => { + this.getHistoryDB = this.cachingProxy.proxifyWithCache( + this.dbConnector.getHistory, + 'getHistory', + this.dbConnector + ); + this.getTrendsDB = this.cachingProxy.proxifyWithCache( + this.dbConnector.getTrends, + 'getTrends', + this.dbConnector + ); }); } } initDBConnector(datasourceId, datasourceName, options) { - return DBConnector.loadDatasource(datasourceId, datasourceName) - .then(ds => { + return DBConnector.loadDatasource(datasourceId, datasourceName).then((ds) => { const connectorOptions: any = { datasourceId, datasourceName }; if (ds.type === 'influxdb') { connectorOptions.retentionPolicy = options.dbConnectionRetentionPolicy; @@ -143,29 +189,29 @@ export class Zabbix implements ZabbixConnector { let zabbixVersion; let dbConnectorStatus; return this.getVersion() - .then(version => { - zabbixVersion = version; - return this.getAllGroups(); - }) - .then(() => { - if (this.enableDirectDBConnection) { - return this.dbConnector.testDataSource(); - } else { - return Promise.resolve(); - } - }) - .catch(error => { - return Promise.reject(error); - }) - .then(testResult => { - if (testResult) { - dbConnectorStatus = { - dsType: this.dbConnector.datasourceTypeName, - dsName: this.dbConnector.datasourceName - }; - } - return { zabbixVersion, dbConnectorStatus }; - }); + .then((version) => { + zabbixVersion = version; + return this.getAllGroups(); + }) + .then(() => { + if (this.enableDirectDBConnection) { + return this.dbConnector.testDataSource(); + } else { + return Promise.resolve(); + } + }) + .catch((error) => { + return Promise.reject(error); + }) + .then((testResult) => { + if (testResult) { + dbConnectorStatus = { + dsType: this.dbConnector.datasourceTypeName, + dsName: this.dbConnector.datasourceName, + }; + } + return { zabbixVersion, dbConnectorStatus }; + }); } async getVersion() { @@ -196,17 +242,14 @@ export class Zabbix implements ZabbixConnector { getItemsFromTarget(target, options) { const parts = ['group', 'host', 'application', 'itemTag', 'item']; - const filters = _.map(parts, p => target[p].filter); + const filters = _.map(parts, (p) => target[p].filter); return this.getItems(...filters, options); } getHostsFromTarget(target) { const parts = ['group', 'host', 'application']; - const filters = _.map(parts, p => target[p].filter); - return Promise.all([ - this.getHosts(...filters), - this.getApps(...filters), - ]).then(results => { + const filters = _.map(parts, (p) => target[p].filter); + return Promise.all([this.getHosts(...filters), this.getApps(...filters)]).then((results) => { const hosts = results[0]; let apps: AppsResponse = results[1]; if (apps.appFilterEmpty) { @@ -221,24 +264,21 @@ export class Zabbix implements ZabbixConnector { } getGroups(groupFilter) { - return this.getAllGroups() - .then(groups => findByFilter(groups, groupFilter)); + return this.getAllGroups().then((groups) => findByFilter(groups, groupFilter)); } /** * Get list of host belonging to given groups. */ getAllHosts(groupFilter) { - return this.getGroups(groupFilter) - .then(groups => { + return this.getGroups(groupFilter).then((groups) => { const groupids = _.map(groups, 'groupid'); return this.zabbixAPI.getHosts(groupids); }); } getHosts(groupFilter?, hostFilter?) { - return this.getAllHosts(groupFilter) - .then(hosts => findByFilter(hosts, hostFilter)); + return this.getAllHosts(groupFilter).then((hosts) => findByFilter(hosts, hostFilter)); } /** @@ -250,8 +290,7 @@ export class Zabbix implements ZabbixConnector { return []; } - return this.getHosts(groupFilter, hostFilter) - .then(hosts => { + return this.getHosts(groupFilter, hostFilter).then((hosts) => { const hostids = _.map(hosts, 'hostid'); return this.zabbixAPI.getApps(hostids); }); @@ -261,12 +300,10 @@ export class Zabbix implements ZabbixConnector { await this.getVersion(); const skipAppFilter = !this.supportsApplications(); - return this.getHosts(groupFilter, hostFilter) - .then(hosts => { + return this.getHosts(groupFilter, hostFilter).then((hosts) => { const hostids = _.map(hosts, 'hostid'); if (appFilter && !skipAppFilter) { - return this.zabbixAPI.getApps(hostids) - .then(apps => filterByQuery(apps, appFilter)); + return this.zabbixAPI.getApps(hostids).then((apps) => filterByQuery(apps, appFilter)); } else { const appsResponse: AppsResponse = hostids; appsResponse.hostids = hostids; @@ -278,15 +315,17 @@ export class Zabbix implements ZabbixConnector { async getItemTags(groupFilter?, hostFilter?, itemTagFilter?) { const items = await this.getAllItems(groupFilter, hostFilter, null, null, {}); - let tags: ZBXItemTag[] = _.flatten(items.map((item: ZBXItem) => { - if (item.tags) { - return item.tags; - } else { - return []; - } - })); - tags = _.uniqBy(tags, t => t.tag + t.value || ''); - const tagsStr = tags.map(t => ({ name: utils.itemTagToString(t) })); + let tags: ZBXItemTag[] = _.flatten( + items.map((item: ZBXItem) => { + if (item.tags) { + return item.tags; + } else { + return []; + } + }) + ); + tags = _.uniqBy(tags, (t) => t.tag + t.value || ''); + const tagsStr = tags.map((t) => ({ name: utils.itemTagToString(t) })); return findByFilter(tagsStr, itemTagFilter); } @@ -309,7 +348,7 @@ export class Zabbix implements ZabbixConnector { } if (!options.showDisabledItems) { - items = _.filter(items, { 'status': '0' }); + items = _.filter(items, { status: '0' }); } return await this.expandUserMacro(items, false); @@ -317,9 +356,8 @@ export class Zabbix implements ZabbixConnector { expandUserMacro(items, isTriggerItem) { const hostids = getHostIds(items); - return this.getMacros(hostids) - .then(macros => { - _.forEach(items, item => { + return this.getMacros(hostids).then((macros) => { + _.forEach(items, (item) => { if (utils.containsMacro(isTriggerItem ? item.url : item.name)) { if (isTriggerItem) { item.url = utils.replaceMacro(item, macros, isTriggerItem); @@ -333,22 +371,23 @@ export class Zabbix implements ZabbixConnector { } getItems(groupFilter?, hostFilter?, appFilter?, itemTagFilter?, itemFilter?, options = {}) { - return this.getAllItems(groupFilter, hostFilter, appFilter, itemTagFilter, options) - .then(items => filterByQuery(items, itemFilter)); + return this.getAllItems(groupFilter, hostFilter, appFilter, itemTagFilter, options).then((items) => + filterByQuery(items, itemFilter) + ); } getItemValues(groupFilter?, hostFilter?, appFilter?, itemFilter?, options: any = {}) { - return this.getItems(groupFilter, hostFilter, appFilter, null, itemFilter, options).then(items => { + return this.getItems(groupFilter, hostFilter, appFilter, null, itemFilter, options).then((items) => { let timeRange = [moment().subtract(2, 'h').unix(), moment().unix()]; if (options.range) { timeRange = [options.range.from.unix(), options.range.to.unix()]; } const [timeFrom, timeTo] = timeRange; - return this.zabbixAPI.getHistory(items, timeFrom, timeTo).then(history => { + return this.zabbixAPI.getHistory(items, timeFrom, timeTo).then((history) => { if (history) { - const values = _.uniq(history.map(v => v.value)); - return values.map(value => ({ name: value })); + const values = _.uniq(history.map((v) => v.value)); + return values.map((value) => ({ name: value })); } else { return []; } @@ -357,44 +396,40 @@ export class Zabbix implements ZabbixConnector { } getITServices(itServiceFilter) { - return this.zabbixAPI.getITService() - .then(itServices => findByFilter(itServices, itServiceFilter)); + return this.zabbixAPI.getITService().then((itServices) => findByFilter(itServices, itServiceFilter)); } getProblems(groupFilter, hostFilter, appFilter, proxyFilter?, options?): Promise { const promises = [ this.getGroups(groupFilter), this.getHosts(groupFilter, hostFilter), - this.getApps(groupFilter, hostFilter, appFilter) + this.getApps(groupFilter, hostFilter, appFilter), ]; return Promise.all(promises) - .then(results => { - const [filteredGroups, filteredHosts, filteredApps] = results; - const query: any = {}; + .then((results) => { + const [filteredGroups, filteredHosts, filteredApps] = results; + const query: any = {}; - if (appFilter) { - query.applicationids = _.flatten(_.map(filteredApps, 'applicationid')); - } - if (hostFilter && hostFilter !== '/.*/') { - query.hostids = _.map(filteredHosts, 'hostid'); - } - if (groupFilter) { - query.groupids = _.map(filteredGroups, 'groupid'); - } + if (appFilter) { + query.applicationids = _.flatten(_.map(filteredApps, 'applicationid')); + } + if (hostFilter && hostFilter !== '/.*/') { + query.hostids = _.map(filteredHosts, 'hostid'); + } + if (groupFilter) { + query.groupids = _.map(filteredGroups, 'groupid'); + } - return query; - }) - .then(query => this.zabbixAPI.getProblems(query.groupids, query.hostids, query.applicationids, options)) - .then(problems => { - const triggerids = problems?.map(problem => problem.objectid); - return Promise.all([ - Promise.resolve(problems), - this.zabbixAPI.getTriggersByIds(triggerids) - ]); - }) - .then(([problems, triggers]) => joinTriggersWithProblems(problems, triggers)) - .then(triggers => this.filterTriggersByProxy(triggers, proxyFilter)); + return query; + }) + .then((query) => this.zabbixAPI.getProblems(query.groupids, query.hostids, query.applicationids, options)) + .then((problems) => { + const triggerids = problems?.map((problem) => problem.objectid); + return Promise.all([Promise.resolve(problems), this.zabbixAPI.getTriggersByIds(triggerids)]); + }) + .then(([problems, triggers]) => joinTriggersWithProblems(problems, triggers)) + .then((triggers) => this.filterTriggersByProxy(triggers, proxyFilter)); // .then(triggers => this.expandUserMacro.bind(this)(triggers, true)); } @@ -404,42 +439,41 @@ export class Zabbix implements ZabbixConnector { const promises = [ this.getGroups(groupFilter), this.getHosts(groupFilter, hostFilter), - this.getApps(groupFilter, hostFilter, appFilter) + this.getApps(groupFilter, hostFilter, appFilter), ]; return Promise.all(promises) - .then(results => { - const [filteredGroups, filteredHosts, filteredApps] = results; - const query: any = {}; + .then((results) => { + const [filteredGroups, filteredHosts, filteredApps] = results; + const query: any = {}; - if (appFilter) { - query.applicationids = _.flatten(_.map(filteredApps, 'applicationid')); - } - if (hostFilter) { - query.hostids = _.map(filteredHosts, 'hostid'); - } - if (groupFilter) { - query.groupids = _.map(filteredGroups, 'groupid'); - } + if (appFilter) { + query.applicationids = _.flatten(_.map(filteredApps, 'applicationid')); + } + if (hostFilter) { + query.hostids = _.map(filteredHosts, 'hostid'); + } + if (groupFilter) { + query.groupids = _.map(filteredGroups, 'groupid'); + } - return query; - }) - .then(query => this.zabbixAPI.getEventsHistory(query.groupids, query.hostids, query.applicationids, options)) - .then(problems => { - const triggerids = problems?.map(problem => problem.objectid); - return Promise.all([Promise.resolve(problems), this.zabbixAPI.getTriggersByIds(triggerids)]); - }) - .then(([problems, triggers]) => joinTriggersWithEvents(problems, triggers, { valueFromEvent })) - .then(triggers => this.filterTriggersByProxy(triggers, proxyFilter)); + return query; + }) + .then((query) => this.zabbixAPI.getEventsHistory(query.groupids, query.hostids, query.applicationids, options)) + .then((problems) => { + const triggerids = problems?.map((problem) => problem.objectid); + return Promise.all([Promise.resolve(problems), this.zabbixAPI.getTriggersByIds(triggerids)]); + }) + .then(([problems, triggers]) => joinTriggersWithEvents(problems, triggers, { valueFromEvent })) + .then((triggers) => this.filterTriggersByProxy(triggers, proxyFilter)); // .then(triggers => this.expandUserMacro.bind(this)(triggers, true)); } filterTriggersByProxy(triggers, proxyFilter) { - return this.getFilteredProxies(proxyFilter) - .then(proxies => { + return this.getFilteredProxies(proxyFilter).then((proxies) => { if (proxyFilter && proxyFilter !== '/.*/' && triggers) { - const proxy_ids = proxies.map(proxy => proxy.proxyid); - triggers = triggers.filter(trigger => { + const proxy_ids = proxies.map((proxy) => proxy.proxyid); + triggers = triggers.filter((trigger) => { for (let i = 0; i < trigger.hosts.length; i++) { const host = trigger.hosts[i]; if (proxy_ids.includes(host.proxy_hostid)) { @@ -454,9 +488,8 @@ export class Zabbix implements ZabbixConnector { } getFilteredProxies(proxyFilter) { - return this.zabbixAPI.getProxies() - .then(proxies => { - proxies.forEach(proxy => proxy.name = proxy.host); + return this.zabbixAPI.getProxies().then((proxies) => { + proxies.forEach((proxy) => (proxy.name = proxy.host)); return findByFilter(proxies, proxyFilter); }); } @@ -464,32 +497,35 @@ export class Zabbix implements ZabbixConnector { getHistoryTS(items, timeRange, request) { const [timeFrom, timeTo] = timeRange; if (this.enableDirectDBConnection) { - return this.getHistoryDB(items, timeFrom, timeTo, request) - .then(history => responseHandler.dataResponseToTimeSeries(history, items, request)); + return this.getHistoryDB(items, timeFrom, timeTo, request).then((history) => + responseHandler.dataResponseToTimeSeries(history, items, request) + ); } else { - return this.zabbixAPI.getHistory(items, timeFrom, timeTo) - .then(history => responseHandler.handleHistory(history, items)); + return this.zabbixAPI + .getHistory(items, timeFrom, timeTo) + .then((history) => responseHandler.handleHistory(history, items)); } } getTrends(items, timeRange, request) { const [timeFrom, timeTo] = timeRange; if (this.enableDirectDBConnection) { - return this.getTrendsDB(items, timeFrom, timeTo, request) - .then(history => responseHandler.dataResponseToTimeSeries(history, items, request)); + return this.getTrendsDB(items, timeFrom, timeTo, request).then((history) => + responseHandler.dataResponseToTimeSeries(history, items, request) + ); } else { const valueType = request.consolidateBy || request.valueType; - return this.zabbixAPI.getTrend(items, timeFrom, timeTo) - .then(history => responseHandler.handleTrends(history, items, valueType)) - .then(responseHandler.sortTimeseries); // Sort trend data, issue #202 + return this.zabbixAPI + .getTrend(items, timeFrom, timeTo) + .then((history) => responseHandler.handleTrends(history, items, valueType)) + .then(responseHandler.sortTimeseries); // Sort trend data, issue #202 } } getHistoryText(items, timeRange, target) { const [timeFrom, timeTo] = timeRange; if (items.length) { - return this.zabbixAPI.getHistory(items, timeFrom, timeTo) - .then(history => { + return this.zabbixAPI.getHistory(items, timeFrom, timeTo).then((history) => { if (target.resultFormat === 'table') { return responseHandler.handleHistoryAsTable(history, items, target); } else { @@ -505,14 +541,14 @@ export class Zabbix implements ZabbixConnector { const itServiceIds = _.map(itservices, 'serviceid'); if (this.supportSLA()) { const slaResponse = await this.zabbixAPI.getSLA60(itServiceIds, timeRange, options); - return _.map(itServiceIds, serviceid => { - const itservice = _.find(itservices, { 'serviceid': serviceid }); + return _.map(itServiceIds, (serviceid) => { + const itservice = _.find(itservices, { serviceid: serviceid }); return responseHandler.handleSLAResponse(itservice, target.slaProperty, slaResponse); }); } const slaResponse = await this.zabbixAPI.getSLA(itServiceIds, timeRange, options); - return _.map(itServiceIds, serviceid => { - const itservice = _.find(itservices, { 'serviceid': serviceid }); + return _.map(itServiceIds, (serviceid) => { + const itservice = _.find(itservices, { serviceid: serviceid }); return responseHandler.handleSLAResponse(itservice, target.slaProperty, slaResponse); }); } @@ -527,7 +563,7 @@ export class Zabbix implements ZabbixConnector { * @return array with finded element or empty array */ function findByName(list, name) { - const finded = _.find(list, { 'name': name }); + const finded = _.find(list, { name: name }); if (finded) { return [finded]; } else { @@ -544,7 +580,7 @@ function findByName(list, name) { * @return {[type]} array with finded element or empty array */ function filterByName(list, name) { - const finded = _.filter(list, { 'name': name }); + const finded = _.filter(list, { name: name }); if (finded) { return finded; } else { @@ -576,7 +612,7 @@ function filterByQuery(list, filter) { } function getHostIds(items) { - const hostIds = _.map(items, item => { + const hostIds = _.map(items, (item) => { return _.map(item.hosts, 'hostid'); }); return _.uniq(_.flatten(hostIds)); @@ -587,7 +623,7 @@ function filterItemsByTag(items: any[], itemTagFilter: string) { const filterPattern = utils.buildRegex(itemTagFilter); return items.filter((item) => { if (item.tags) { - const tags: string[] = item.tags.map(t => utils.itemTagToString(t)); + const tags: string[] = item.tags.map((t) => utils.itemTagToString(t)); return tags.some((tag) => { return filterPattern.test(tag); }); @@ -596,9 +632,9 @@ function filterItemsByTag(items: any[], itemTagFilter: string) { } }); } else { - return items.filter(item => { + return items.filter((item) => { if (item.tags) { - const tags: string[] = item.tags.map(t => utils.itemTagToString(t)); + const tags: string[] = item.tags.map((t) => utils.itemTagToString(t)); return tags.includes(itemTagFilter); } else { return false;