Added timeShift() function, closes #307.
This commit is contained in:
@@ -251,6 +251,23 @@ function findNearestLeft(series, point) {
|
|||||||
return nearestLeft;
|
return nearestLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function timeShift(interval, range) {
|
||||||
|
let shift = utils.parseTimeShiftInterval(interval) / 1000;
|
||||||
|
return range.map(time => {
|
||||||
|
return time - shift;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function unShiftTimeSeries(interval, datapoints) {
|
||||||
|
let unshift = utils.parseTimeShiftInterval(interval);
|
||||||
|
return datapoints.map(dp => {
|
||||||
|
return [
|
||||||
|
dp[0],
|
||||||
|
dp[1] + unshift
|
||||||
|
];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let metricFunctions = {
|
let metricFunctions = {
|
||||||
groupBy: groupByWrapper,
|
groupBy: groupByWrapper,
|
||||||
scale: scale,
|
scale: scale,
|
||||||
@@ -263,6 +280,7 @@ let metricFunctions = {
|
|||||||
sumSeries: sumSeries,
|
sumSeries: sumSeries,
|
||||||
top: _.partial(limit, 'top'),
|
top: _.partial(limit, 'top'),
|
||||||
bottom: _.partial(limit, 'bottom'),
|
bottom: _.partial(limit, 'bottom'),
|
||||||
|
timeShift: timeShift,
|
||||||
setAlias: setAlias
|
setAlias: setAlias
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -280,6 +298,7 @@ export default {
|
|||||||
MIN: MIN,
|
MIN: MIN,
|
||||||
MAX: MAX,
|
MAX: MAX,
|
||||||
MEDIAN: MEDIAN,
|
MEDIAN: MEDIAN,
|
||||||
|
unShiftTimeSeries: unShiftTimeSeries,
|
||||||
|
|
||||||
get aggregationFunctions() {
|
get aggregationFunctions() {
|
||||||
return aggregationFunctions;
|
return aggregationFunctions;
|
||||||
|
|||||||
@@ -50,18 +50,26 @@ class ZabbixAPIDatasource {
|
|||||||
* @return {Object} Grafana metrics object with timeseries data for each target.
|
* @return {Object} Grafana metrics object with timeseries data for each target.
|
||||||
*/
|
*/
|
||||||
query(options) {
|
query(options) {
|
||||||
var timeFrom = Math.ceil(dateMath.parse(options.range.from) / 1000);
|
let timeFrom = Math.ceil(dateMath.parse(options.range.from) / 1000);
|
||||||
var timeTo = Math.ceil(dateMath.parse(options.range.to) / 1000);
|
let timeTo = Math.ceil(dateMath.parse(options.range.to) / 1000);
|
||||||
|
|
||||||
var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);
|
let useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);
|
||||||
var useTrends = (timeFrom <= useTrendsFrom) && this.trends;
|
let useTrends = (timeFrom <= useTrendsFrom) && this.trends;
|
||||||
|
|
||||||
// Create request for each target
|
// Create request for each target
|
||||||
var promises = _.map(options.targets, target => {
|
let promises = _.map(options.targets, target => {
|
||||||
// Prevent changes of original object
|
// Prevent changes of original object
|
||||||
target = _.cloneDeep(target);
|
target = _.cloneDeep(target);
|
||||||
this.replaceTargetVariables(target, options);
|
this.replaceTargetVariables(target, options);
|
||||||
|
|
||||||
|
// Apply Time-related functions (timeShift(), etc)
|
||||||
|
let timeFunctions = bindFunctionDefs(target.functions, 'Time');
|
||||||
|
if (timeFunctions.length) {
|
||||||
|
const [time_from, time_to] = sequence(timeFunctions)([timeFrom, timeTo]);
|
||||||
|
timeFrom = time_from;
|
||||||
|
timeTo = time_to;
|
||||||
|
}
|
||||||
|
|
||||||
// Metrics or Text query mode
|
// Metrics or Text query mode
|
||||||
if (target.mode !== 1) {
|
if (target.mode !== 1) {
|
||||||
// Migrate old targets
|
// Migrate old targets
|
||||||
@@ -175,11 +183,28 @@ class ZabbixAPIDatasource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply alias functions
|
// Apply alias functions
|
||||||
_.each(timeseries_data, sequence(aliasFunctions));
|
_.forEach(timeseries_data, sequence(aliasFunctions));
|
||||||
|
|
||||||
|
// Apply Time-related functions (timeShift(), etc)
|
||||||
|
// Find timeShift() function and get specified trend value
|
||||||
|
this.applyTimeShiftFunction(timeseries_data, target);
|
||||||
|
|
||||||
return timeseries_data;
|
return timeseries_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyTimeShiftFunction(timeseries_data, target) {
|
||||||
|
// Find timeShift() function and get specified interval
|
||||||
|
let timeShiftFunc = _.find(target.functions, (func) => {
|
||||||
|
return func.def.name === 'timeShift';
|
||||||
|
});
|
||||||
|
if (timeShiftFunc) {
|
||||||
|
let shift = timeShiftFunc.params[0];
|
||||||
|
_.forEach(timeseries_data, (series) => {
|
||||||
|
series.datapoints = dataProcessor.unShiftTimeSeries(shift, series.datapoints);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
queryTextData(target, timeFrom, timeTo) {
|
queryTextData(target, timeFrom, timeTo) {
|
||||||
let options = {
|
let options = {
|
||||||
itemtype: 'text'
|
itemtype: 'text'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ var categories = {
|
|||||||
Aggregate: [],
|
Aggregate: [],
|
||||||
Filter: [],
|
Filter: [],
|
||||||
Trends: [],
|
Trends: [],
|
||||||
|
Time: [],
|
||||||
Alias: []
|
Alias: []
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -21,6 +22,8 @@ function addFuncDef(funcDef) {
|
|||||||
index[funcDef.shortName || funcDef.name] = funcDef;
|
index[funcDef.shortName || funcDef.name] = funcDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform
|
||||||
|
|
||||||
addFuncDef({
|
addFuncDef({
|
||||||
name: 'groupBy',
|
name: 'groupBy',
|
||||||
category: 'Transform',
|
category: 'Transform',
|
||||||
@@ -47,6 +50,8 @@ addFuncDef({
|
|||||||
defaultParams: [],
|
defaultParams: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Aggregate
|
||||||
|
|
||||||
addFuncDef({
|
addFuncDef({
|
||||||
name: 'sumSeries',
|
name: 'sumSeries',
|
||||||
category: 'Aggregate',
|
category: 'Aggregate',
|
||||||
@@ -100,6 +105,8 @@ addFuncDef({
|
|||||||
defaultParams: ['1m', 'avg'],
|
defaultParams: ['1m', 'avg'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Filter
|
||||||
|
|
||||||
addFuncDef({
|
addFuncDef({
|
||||||
name: 'top',
|
name: 'top',
|
||||||
category: 'Filter',
|
category: 'Filter',
|
||||||
@@ -120,6 +127,8 @@ addFuncDef({
|
|||||||
defaultParams: [5, 'avg'],
|
defaultParams: [5, 'avg'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Trends
|
||||||
|
|
||||||
addFuncDef({
|
addFuncDef({
|
||||||
name: 'trendValue',
|
name: 'trendValue',
|
||||||
category: 'Trends',
|
category: 'Trends',
|
||||||
@@ -129,6 +138,17 @@ addFuncDef({
|
|||||||
defaultParams: ['avg'],
|
defaultParams: ['avg'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Time
|
||||||
|
|
||||||
|
addFuncDef({
|
||||||
|
name: 'timeShift',
|
||||||
|
category: 'Time',
|
||||||
|
params: [
|
||||||
|
{ name: 'interval', type: 'string', options: ['24h', '7d', '1M', '+24h', '-24h']}
|
||||||
|
],
|
||||||
|
defaultParams: ['24h'],
|
||||||
|
});
|
||||||
|
|
||||||
addFuncDef({
|
addFuncDef({
|
||||||
name: 'setAlias',
|
name: 'setAlias',
|
||||||
category: 'Alias',
|
category: 'Alias',
|
||||||
|
|||||||
@@ -59,6 +59,20 @@ export function parseInterval(interval) {
|
|||||||
return moment.duration(Number(momentInterval[1]), momentInterval[2]).valueOf();
|
return moment.duration(Number(momentInterval[1]), momentInterval[2]).valueOf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parseTimeShiftInterval(interval) {
|
||||||
|
let intervalPattern = /^([\+\-]*)([\d]+)(y|M|w|d|h|m|s)/g;
|
||||||
|
let momentInterval = intervalPattern.exec(interval);
|
||||||
|
let duration = 0;
|
||||||
|
|
||||||
|
if (momentInterval[1] === '+') {
|
||||||
|
duration = 0 - moment.duration(Number(momentInterval[2]), momentInterval[3]).valueOf();
|
||||||
|
} else {
|
||||||
|
duration = moment.duration(Number(momentInterval[2]), momentInterval[3]).valueOf();
|
||||||
|
}
|
||||||
|
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format acknowledges.
|
* Format acknowledges.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user