Added timeShift() function, closes #307.
This commit is contained in:
@@ -251,6 +251,23 @@ function findNearestLeft(series, point) {
|
||||
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 = {
|
||||
groupBy: groupByWrapper,
|
||||
scale: scale,
|
||||
@@ -263,6 +280,7 @@ let metricFunctions = {
|
||||
sumSeries: sumSeries,
|
||||
top: _.partial(limit, 'top'),
|
||||
bottom: _.partial(limit, 'bottom'),
|
||||
timeShift: timeShift,
|
||||
setAlias: setAlias
|
||||
};
|
||||
|
||||
@@ -280,6 +298,7 @@ export default {
|
||||
MIN: MIN,
|
||||
MAX: MAX,
|
||||
MEDIAN: MEDIAN,
|
||||
unShiftTimeSeries: unShiftTimeSeries,
|
||||
|
||||
get aggregationFunctions() {
|
||||
return aggregationFunctions;
|
||||
|
||||
@@ -50,18 +50,26 @@ class ZabbixAPIDatasource {
|
||||
* @return {Object} Grafana metrics object with timeseries data for each target.
|
||||
*/
|
||||
query(options) {
|
||||
var timeFrom = Math.ceil(dateMath.parse(options.range.from) / 1000);
|
||||
var timeTo = Math.ceil(dateMath.parse(options.range.to) / 1000);
|
||||
let timeFrom = Math.ceil(dateMath.parse(options.range.from) / 1000);
|
||||
let timeTo = Math.ceil(dateMath.parse(options.range.to) / 1000);
|
||||
|
||||
var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);
|
||||
var useTrends = (timeFrom <= useTrendsFrom) && this.trends;
|
||||
let useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);
|
||||
let useTrends = (timeFrom <= useTrendsFrom) && this.trends;
|
||||
|
||||
// Create request for each target
|
||||
var promises = _.map(options.targets, target => {
|
||||
let promises = _.map(options.targets, target => {
|
||||
// Prevent changes of original object
|
||||
target = _.cloneDeep(target);
|
||||
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
|
||||
if (target.mode !== 1) {
|
||||
// Migrate old targets
|
||||
@@ -175,11 +183,28 @@ class ZabbixAPIDatasource {
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
let options = {
|
||||
itemtype: 'text'
|
||||
|
||||
@@ -7,6 +7,7 @@ var categories = {
|
||||
Aggregate: [],
|
||||
Filter: [],
|
||||
Trends: [],
|
||||
Time: [],
|
||||
Alias: []
|
||||
};
|
||||
|
||||
@@ -21,6 +22,8 @@ function addFuncDef(funcDef) {
|
||||
index[funcDef.shortName || funcDef.name] = funcDef;
|
||||
}
|
||||
|
||||
// Transform
|
||||
|
||||
addFuncDef({
|
||||
name: 'groupBy',
|
||||
category: 'Transform',
|
||||
@@ -47,6 +50,8 @@ addFuncDef({
|
||||
defaultParams: [],
|
||||
});
|
||||
|
||||
// Aggregate
|
||||
|
||||
addFuncDef({
|
||||
name: 'sumSeries',
|
||||
category: 'Aggregate',
|
||||
@@ -100,6 +105,8 @@ addFuncDef({
|
||||
defaultParams: ['1m', 'avg'],
|
||||
});
|
||||
|
||||
// Filter
|
||||
|
||||
addFuncDef({
|
||||
name: 'top',
|
||||
category: 'Filter',
|
||||
@@ -120,6 +127,8 @@ addFuncDef({
|
||||
defaultParams: [5, 'avg'],
|
||||
});
|
||||
|
||||
// Trends
|
||||
|
||||
addFuncDef({
|
||||
name: 'trendValue',
|
||||
category: 'Trends',
|
||||
@@ -129,6 +138,17 @@ addFuncDef({
|
||||
defaultParams: ['avg'],
|
||||
});
|
||||
|
||||
// Time
|
||||
|
||||
addFuncDef({
|
||||
name: 'timeShift',
|
||||
category: 'Time',
|
||||
params: [
|
||||
{ name: 'interval', type: 'string', options: ['24h', '7d', '1M', '+24h', '-24h']}
|
||||
],
|
||||
defaultParams: ['24h'],
|
||||
});
|
||||
|
||||
addFuncDef({
|
||||
name: 'setAlias',
|
||||
category: 'Alias',
|
||||
|
||||
@@ -59,6 +59,20 @@ export function parseInterval(interval) {
|
||||
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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user