Added timeShift() function, closes #307.

This commit is contained in:
Alexander Zobnin
2016-11-17 17:48:08 +03:00
parent 092b6c897c
commit 54c03e6ece
4 changed files with 84 additions and 6 deletions

View File

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

View File

@@ -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'

View File

@@ -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',

View File

@@ -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.
* *