datasource: convert to TS

This commit is contained in:
Alexander Zobnin
2020-05-07 11:33:15 +03:00
parent b704bf23c1
commit 44660476ca
2 changed files with 84 additions and 63 deletions

View File

@@ -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;}

View File

@@ -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) {