diff --git a/src/datasource-zabbix/datasource.js b/src/datasource-zabbix/datasource.ts similarity index 83% rename from src/datasource-zabbix/datasource.js rename to src/datasource-zabbix/datasource.ts index cd70e96..e4a0bb6 100644 --- a/src/datasource-zabbix/datasource.js +++ b/src/datasource-zabbix/datasource.ts @@ -14,9 +14,33 @@ import { VariableQueryTypes } from './types'; const DEFAULT_ZABBIX_VERSION = 3; export class ZabbixDatasource { + name: string; + url: string; + basicAuth: any; + withCredentials: any; + + username: string; + password: string; + trends: boolean; + trendsFrom: string; + trendsRange: string; + cacheTTL: any; + alertingEnabled: boolean; + addThresholds: boolean; + alertingMinSeverity: string; + disableReadOnlyUsersAck: boolean; + zabbixVersion: string; + enableDirectDBConnection: boolean; + dbConnectionDatasourceId: number; + dbConnectionDatasourceName: string; + dbConnectionRetentionPolicy: string; + enableDebugLog: boolean; + zabbix: any; + + replaceTemplateVars: (templateSrv: any, target: any, scopedVars?: any) => any; /** @ngInject */ - constructor(instanceSettings, templateSrv, zabbixAlertingSrv) { + constructor(instanceSettings, private templateSrv, private zabbixAlertingSrv) { this.templateSrv = templateSrv; this.zabbixAlertingSrv = zabbixAlertingSrv; @@ -43,7 +67,7 @@ export class ZabbixDatasource { this.trendsRange = jsonData.trendsRange || '4d'; // Set cache update interval - var ttl = jsonData.cacheTTL || '1h'; + const ttl = jsonData.cacheTTL || '1h'; this.cacheTTL = utils.parseInterval(ttl); // Alerting options @@ -61,7 +85,7 @@ export class ZabbixDatasource { this.dbConnectionDatasourceName = jsonData.dbConnectionDatasourceName; this.dbConnectionRetentionPolicy = jsonData.dbConnectionRetentionPolicy; - let zabbixOptions = { + const zabbixOptions = { url: this.url, username: this.username, password: this.password, @@ -103,7 +127,7 @@ export class ZabbixDatasource { } // Create request for each target - let promises = _.map(options.targets, t => { + const promises = _.map(options.targets, t => { // Don't request for hidden targets if (t.hide) { return []; @@ -123,15 +147,15 @@ export class ZabbixDatasource { this.replaceTargetVariables(target, options); // Apply Time-related functions (timeShift(), etc) - let timeFunctions = bindFunctionDefs(target.functions, 'Time'); + const timeFunctions = bindFunctionDefs(target.functions, 'Time'); if (timeFunctions.length) { const [time_from, time_to] = utils.sequence(timeFunctions)([timeFrom, timeTo]); timeFrom = time_from; timeTo = time_to; } - let timeRange = [timeFrom, timeTo]; + const timeRange = [timeFrom, timeTo]; - let useTrends = this.isUseTrends(timeRange); + const useTrends = this.isUseTrends(timeRange); // Metrics or Text query if (!target.queryType || target.queryType === c.MODE_METRICS || target.queryType === c.MODE_TEXT) { @@ -175,7 +199,7 @@ export class ZabbixDatasource { */ queryNumericData(target, timeRange, useTrends, options) { let queryStart, queryEnd; - let getItemOptions = { + const getItemOptions = { itemtype: 'num' }; return this.zabbix.getItemsFromTarget(target, getItemOptions) @@ -185,7 +209,7 @@ export class ZabbixDatasource { }).then(result => { queryEnd = new Date().getTime(); if (this.enableDebugLog) { - console.debug(`Datasource::Performance Query Time (${this.name}): ${queryEnd - queryStart}`); + console.log(`Datasource::Performance Query Time (${this.name}): ${queryEnd - queryStart}`); } return result; }); @@ -212,18 +236,18 @@ export class ZabbixDatasource { getTrendValueType(target) { // Find trendValue() function and get specified trend value - var trendFunctions = _.map(metricFunctions.getCategories()['Trends'], 'name'); - var trendValueFunc = _.find(target.functions, func => { + const trendFunctions = _.map(metricFunctions.getCategories()['Trends'], 'name'); + const trendValueFunc = _.find(target.functions, func => { return _.includes(trendFunctions, func.def.name); }); return trendValueFunc ? trendValueFunc.params[0] : "avg"; } applyDataProcessingFunctions(timeseries_data, target) { - let transformFunctions = bindFunctionDefs(target.functions, 'Transform'); - let aggregationFunctions = bindFunctionDefs(target.functions, 'Aggregate'); - let filterFunctions = bindFunctionDefs(target.functions, 'Filter'); - let aliasFunctions = bindFunctionDefs(target.functions, 'Alias'); + const transformFunctions = bindFunctionDefs(target.functions, 'Transform'); + const aggregationFunctions = bindFunctionDefs(target.functions, 'Aggregate'); + const filterFunctions = bindFunctionDefs(target.functions, 'Filter'); + const aliasFunctions = bindFunctionDefs(target.functions, 'Alias'); // Apply transformation functions timeseries_data = _.cloneDeep(_.map(timeseries_data, timeseries => { @@ -241,8 +265,8 @@ export class ZabbixDatasource { let dp = _.map(timeseries_data, 'datapoints'); dp = utils.sequence(aggregationFunctions)(dp); - let aggFuncNames = _.map(metricFunctions.getCategories()['Aggregate'], 'name'); - let lastAgg = _.findLast(target.functions, func => { + const aggFuncNames = _.map(metricFunctions.getCategories()['Aggregate'], 'name'); + const lastAgg = _.findLast(target.functions, func => { return _.includes(aggFuncNames, func.def.name); }); @@ -264,11 +288,11 @@ export class ZabbixDatasource { applyTimeShiftFunction(timeseries_data, target) { // Find timeShift() function and get specified interval - let timeShiftFunc = _.find(target.functions, (func) => { + const timeShiftFunc = _.find(target.functions, (func) => { return func.def.name === 'timeShift'; }); if (timeShiftFunc) { - let shift = timeShiftFunc.params[0]; + const shift = timeShiftFunc.params[0]; _.forEach(timeseries_data, (series) => { series.datapoints = dataProcessor.unShiftTimeSeries(shift, series.datapoints); }); @@ -279,7 +303,7 @@ export class ZabbixDatasource { * Query target data for Text */ queryTextData(target, timeRange) { - let options = { + const options = { itemtype: 'text' }; return this.zabbix.getItemsFromTarget(target, options) @@ -332,14 +356,14 @@ export class ZabbixDatasource { } queryTriggersData(target, timeRange) { - let [timeFrom, timeTo] = timeRange; + const [timeFrom, timeTo] = timeRange; return this.zabbix.getHostsFromTarget(target) .then(results => { - let [hosts, apps] = results; + const [hosts, apps] = results; if (hosts.length) { - let hostids = _.map(hosts, 'hostid'); - let appids = _.map(apps, 'applicationid'); - let options = { + const hostids = _.map(hosts, 'hostid'); + const appids = _.map(apps, 'applicationid'); + const options = { minSeverity: target.triggers.minSeverity, acknowledged: target.triggers.acknowledged, count: target.triggers.count, @@ -480,16 +504,16 @@ export class ZabbixDatasource { const timeRange = options.range || options.rangeRaw; const timeFrom = Math.ceil(dateMath.parse(timeRange.from) / 1000); const timeTo = Math.ceil(dateMath.parse(timeRange.to) / 1000); - var annotation = options.annotation; - var showOkEvents = annotation.showOkEvents ? c.SHOW_ALL_EVENTS : c.SHOW_OK_EVENTS; + const annotation = options.annotation; + const showOkEvents = annotation.showOkEvents ? c.SHOW_ALL_EVENTS : c.SHOW_OK_EVENTS; // Show all triggers - let triggersOptions = { + const triggersOptions = { showTriggers: c.SHOW_ALL_TRIGGERS, hideHostsInMaintenance: false }; - var getTriggers = this.zabbix.getTriggers(this.replaceTemplateVars(annotation.group, {}), + const getTriggers = this.zabbix.getTriggers(this.replaceTemplateVars(annotation.group, {}), this.replaceTemplateVars(annotation.host, {}), this.replaceTemplateVars(annotation.application, {}), triggersOptions); @@ -497,7 +521,7 @@ export class ZabbixDatasource { return getTriggers.then(triggers => { // Filter triggers by description - let triggerName = this.replaceTemplateVars(annotation.trigger, {}); + const triggerName = this.replaceTemplateVars(annotation.trigger, {}); if (utils.isRegex(triggerName)) { triggers = _.filter(triggers, trigger => { return utils.buildRegex(triggerName).test(trigger.description); @@ -513,11 +537,11 @@ export class ZabbixDatasource { return Number(trigger.priority) >= Number(annotation.minseverity); }); - var objectids = _.map(triggers, 'triggerid'); + const objectids = _.map(triggers, 'triggerid'); return this.zabbix .getEvents(objectids, timeFrom, timeTo, showOkEvents) .then(events => { - var indexedTriggers = _.keyBy(triggers, 'triggerid'); + const indexedTriggers = _.keyBy(triggers, 'triggerid'); // Hide acknowledged events if option enabled if (annotation.hideAcknowledged) { @@ -533,10 +557,10 @@ export class ZabbixDatasource { } // Show event type (OK or Problem) - let title = Number(event.value) ? 'Problem' : 'OK'; + const title = Number(event.value) ? 'Problem' : 'OK'; - let formattedAcknowledges = utils.formatAcknowledges(event.acknowledges); - let eventName = event.name || indexedTriggers[event.objectid].description; + const formattedAcknowledges = utils.formatAcknowledges(event.acknowledges); + const eventName = event.name || indexedTriggers[event.objectid].description; return { annotation: annotation, time: event.clock * 1000, @@ -555,8 +579,8 @@ export class ZabbixDatasource { * or empty object if no related triggers are finded. */ alertQuery(options) { - let enabled_targets = filterEnabledTargets(options.targets); - let getPanelItems = _.map(enabled_targets, t => { + const enabled_targets = filterEnabledTargets(options.targets); + const getPanelItems = _.map(enabled_targets, t => { let target = _.cloneDeep(t); target = migrations.migrate(target); this.replaceTargetVariables(target, options); @@ -565,8 +589,8 @@ export class ZabbixDatasource { return Promise.all(getPanelItems) .then(results => { - let items = _.flatten(results); - let itemids = _.map(items, 'itemid'); + const items = _.flatten(results); + const itemids = _.map(items, 'itemid'); if (itemids.length === 0) { return []; @@ -584,12 +608,12 @@ export class ZabbixDatasource { let state = 'ok'; - let firedTriggers = _.filter(triggers, {value: '1'}); + const firedTriggers = _.filter(triggers, {value: '1'}); if (firedTriggers.length) { state = 'alerting'; } - let thresholds = _.map(triggers, trigger => { + const thresholds = _.map(triggers, trigger => { return getTriggerThreshold(trigger.expression); }); @@ -603,7 +627,7 @@ export class ZabbixDatasource { // Replace template variables replaceTargetVariables(target, options) { - let parts = ['group', 'host', 'application', 'item']; + const parts = ['group', 'host', 'application', 'item']; _.forEach(parts, p => { if (target[p] && target[p].filter) { target[p].filter = this.replaceTemplateVars(target[p].filter, options.scopedVars); @@ -623,10 +647,10 @@ export class ZabbixDatasource { } isUseTrends(timeRange) { - let [timeFrom, timeTo] = timeRange; - let useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000); - let useTrendsRange = Math.ceil(utils.parseInterval(this.trendsRange) / 1000); - let useTrends = this.trends && ( + const [timeFrom, timeTo] = timeRange; + const useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000); + const useTrendsRange = Math.ceil(utils.parseInterval(this.trendsRange) / 1000); + const useTrends = this.trends && ( (timeFrom < useTrendsFrom) || (timeTo - timeFrom > useTrendsRange) ); @@ -635,20 +659,20 @@ export class ZabbixDatasource { } function bindFunctionDefs(functionDefs, category) { - var aggregationFunctions = _.map(metricFunctions.getCategories()[category], 'name'); - var aggFuncDefs = _.filter(functionDefs, function(func) { + const aggregationFunctions = _.map(metricFunctions.getCategories()[category], 'name'); + const aggFuncDefs = _.filter(functionDefs, func => { return _.includes(aggregationFunctions, func.def.name); }); - return _.map(aggFuncDefs, function(func) { - var funcInstance = metricFunctions.createFuncInstance(func.def, func.params); + return _.map(aggFuncDefs, func => { + const funcInstance = metricFunctions.createFuncInstance(func.def, func.params); return funcInstance.bindFunction(dataProcessor.metricFunctions); }); } function getConsolidateBy(target) { let consolidateBy; - let funcDef = _.find(target.functions, func => { + const funcDef = _.find(target.functions, func => { return func.def.name === 'consolidateBy'; }); if (funcDef && funcDef.params && funcDef.params.length) { @@ -658,8 +682,8 @@ function getConsolidateBy(target) { } function downsampleSeries(timeseries_data, options) { - let defaultAgg = dataProcessor.aggregationFunctions['avg']; - let consolidateByFunc = dataProcessor.aggregationFunctions[options.consolidateBy] || defaultAgg; + const defaultAgg = dataProcessor.aggregationFunctions['avg']; + const consolidateByFunc = dataProcessor.aggregationFunctions[options.consolidateBy] || defaultAgg; return _.map(timeseries_data, timeseries => { if (timeseries.datapoints.length > options.maxDataPoints) { timeseries.datapoints = dataProcessor @@ -691,7 +715,7 @@ export function zabbixTemplateFormat(value) { return utils.escapeRegex(value); } - var escapedValues = _.map(value, utils.escapeRegex); + const escapedValues = _.map(value, utils.escapeRegex); return '(' + escapedValues.join('|') + ')'; } @@ -711,7 +735,7 @@ function zabbixItemIdsTemplateFormat(value) { * /$variable/ -> /a|b|c/ -> /a|b|c/ */ function replaceTemplateVars(templateSrv, target, scopedVars) { - var replacedTarget = templateSrv.replace(target, scopedVars, zabbixTemplateFormat); + let replacedTarget = templateSrv.replace(target, scopedVars, zabbixTemplateFormat); if (target !== replacedTarget && !utils.isRegex(replacedTarget)) { replacedTarget = '/^' + replacedTarget + '$/'; } @@ -725,8 +749,8 @@ function filterEnabledTargets(targets) { } function getTriggerThreshold(expression) { - let thresholdPattern = /.*[<>=]{1,2}([\d\.]+)/; - let finded_thresholds = expression.match(thresholdPattern); + const thresholdPattern = /.*[<>=]{1,2}([\d\.]+)/; + const finded_thresholds = expression.match(thresholdPattern); if (finded_thresholds && finded_thresholds.length >= 2) { let threshold = finded_thresholds[1]; threshold = Number(threshold); @@ -735,7 +759,3 @@ function getTriggerThreshold(expression) { return null; } } - -// Fix for backward compatibility with lodash 2.4 -if (!_.includes) {_.includes = _.contains;} -if (!_.keyBy) {_.keyBy = _.indexBy;} diff --git a/src/datasource-zabbix/utils.ts b/src/datasource-zabbix/utils.ts index 44bc5a5..5eb68c4 100644 --- a/src/datasource-zabbix/utils.ts +++ b/src/datasource-zabbix/utils.ts @@ -222,10 +222,11 @@ export function escapeRegex(value) { return value.replace(/[\\^$*+?.()|[\]{}\/]/g, '\\$&'); } -export function parseInterval(interval) { +export function parseInterval(interval: string): number { const intervalPattern = /(^[\d]+)(y|M|w|d|h|m|s)/g; const momentInterval: any[] = intervalPattern.exec(interval); - return moment.duration(Number(momentInterval[1]), momentInterval[2]).valueOf(); + const duration = moment.duration(Number(momentInterval[1]), momentInterval[2]); + return (duration.valueOf() as number); } export function parseTimeShiftInterval(interval) {