Add top N and bottom N filter functions, closes #241.
This commit is contained in:
@@ -78,6 +78,38 @@ max(interval)
|
|||||||
```
|
```
|
||||||
**Deprecated**, use `aggregateBy(interval, max)` instead.
|
**Deprecated**, use `aggregateBy(interval, max)` instead.
|
||||||
|
|
||||||
|
|
||||||
|
Filter
|
||||||
|
---------
|
||||||
|
|
||||||
|
### top
|
||||||
|
|
||||||
|
```
|
||||||
|
top(N, value)
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns top N series, sorted by _value_, which can be one of: _avg_, _min_, _max_, _median_.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
top(10, avg)
|
||||||
|
top(5, max)
|
||||||
|
```
|
||||||
|
|
||||||
|
### bottom
|
||||||
|
|
||||||
|
```
|
||||||
|
bottom(N, value)
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns bottom N series, sorted by _value_, which can be one of: _avg_, _min_, _max_, _median_.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
```
|
||||||
|
bottom(5, avg)
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Trends
|
## Trends
|
||||||
|
|
||||||
### trendValue
|
### trendValue
|
||||||
|
|||||||
@@ -116,6 +116,22 @@ export default class DataProcessor {
|
|||||||
return sortByTime(new_timeseries);
|
return sortByTime(new_timeseries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static limit(order, n, orderByFunc, timeseries) {
|
||||||
|
let orderByCallback = DataProcessor.aggregationFunctions[orderByFunc];
|
||||||
|
let sortByIteratee = (ts) => {
|
||||||
|
let values = _.map(ts.datapoints, (point) => {
|
||||||
|
return point[0];
|
||||||
|
});
|
||||||
|
return orderByCallback(values);
|
||||||
|
};
|
||||||
|
let sortedTimeseries = _.sortBy(timeseries, sortByIteratee);
|
||||||
|
if (order === 'bottom') {
|
||||||
|
return sortedTimeseries.slice(0, n);
|
||||||
|
} else {
|
||||||
|
return sortedTimeseries.slice(-n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static AVERAGE(values) {
|
static AVERAGE(values) {
|
||||||
var sum = 0;
|
var sum = 0;
|
||||||
_.each(values, function(value) {
|
_.each(values, function(value) {
|
||||||
@@ -198,6 +214,8 @@ export default class DataProcessor {
|
|||||||
max: _.partial(this.aggregateWrapper, this.MAX),
|
max: _.partial(this.aggregateWrapper, this.MAX),
|
||||||
median: _.partial(this.aggregateWrapper, this.MEDIAN),
|
median: _.partial(this.aggregateWrapper, this.MEDIAN),
|
||||||
sumSeries: this.sumSeries,
|
sumSeries: this.sumSeries,
|
||||||
|
top: _.partial(this.limit, 'top'),
|
||||||
|
bottom: _.partial(this.limit, 'bottom'),
|
||||||
setAlias: this.setAlias,
|
setAlias: this.setAlias,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,11 @@ export class ZabbixAPIDatasource {
|
|||||||
|
|
||||||
_.forEach(target.functions, func => {
|
_.forEach(target.functions, func => {
|
||||||
func.params = _.map(func.params, param => {
|
func.params = _.map(func.params, param => {
|
||||||
|
if (typeof param === 'number') {
|
||||||
|
return +this.templateSrv.replace(param.toString(), options.scopedVars);
|
||||||
|
} else {
|
||||||
return this.templateSrv.replace(param, options.scopedVars);
|
return this.templateSrv.replace(param, options.scopedVars);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -181,6 +185,7 @@ export class ZabbixAPIDatasource {
|
|||||||
return getHistory.then(timeseries_data => {
|
return getHistory.then(timeseries_data => {
|
||||||
let transformFunctions = bindFunctionDefs(target.functions, 'Transform');
|
let transformFunctions = bindFunctionDefs(target.functions, 'Transform');
|
||||||
let aggregationFunctions = bindFunctionDefs(target.functions, 'Aggregate');
|
let aggregationFunctions = bindFunctionDefs(target.functions, 'Aggregate');
|
||||||
|
let filterFunctions = bindFunctionDefs(target.functions, 'Filter');
|
||||||
let aliasFunctions = bindFunctionDefs(target.functions, 'Alias');
|
let aliasFunctions = bindFunctionDefs(target.functions, 'Alias');
|
||||||
|
|
||||||
// Apply transformation functions
|
// Apply transformation functions
|
||||||
@@ -189,6 +194,11 @@ export class ZabbixAPIDatasource {
|
|||||||
return timeseries;
|
return timeseries;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Apply filter functions
|
||||||
|
if (filterFunctions.length) {
|
||||||
|
timeseries_data = sequence(filterFunctions)(timeseries_data);
|
||||||
|
}
|
||||||
|
|
||||||
// Apply aggregations
|
// Apply aggregations
|
||||||
if (aggregationFunctions.length) {
|
if (aggregationFunctions.length) {
|
||||||
let dp = _.map(timeseries_data, 'datapoints');
|
let dp = _.map(timeseries_data, 'datapoints');
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ var index = [];
|
|||||||
var categories = {
|
var categories = {
|
||||||
Transform: [],
|
Transform: [],
|
||||||
Aggregate: [],
|
Aggregate: [],
|
||||||
|
Filter: [],
|
||||||
Trends: [],
|
Trends: [],
|
||||||
Alias: []
|
Alias: []
|
||||||
};
|
};
|
||||||
@@ -99,6 +100,26 @@ addFuncDef({
|
|||||||
defaultParams: ['1m', 'avg'],
|
defaultParams: ['1m', 'avg'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addFuncDef({
|
||||||
|
name: 'top',
|
||||||
|
category: 'Filter',
|
||||||
|
params: [
|
||||||
|
{ name: 'number', type: 'int' },
|
||||||
|
{ name: 'value', type: 'string', options: ['avg', 'min', 'max', 'median'] }
|
||||||
|
],
|
||||||
|
defaultParams: [5, 'avg'],
|
||||||
|
});
|
||||||
|
|
||||||
|
addFuncDef({
|
||||||
|
name: 'bottom',
|
||||||
|
category: 'Filter',
|
||||||
|
params: [
|
||||||
|
{ name: 'number', type: 'int' },
|
||||||
|
{ name: 'value', type: 'string', options: ['avg', 'min', 'max', 'median'] }
|
||||||
|
],
|
||||||
|
defaultParams: [5, 'avg'],
|
||||||
|
});
|
||||||
|
|
||||||
addFuncDef({
|
addFuncDef({
|
||||||
name: 'trendValue',
|
name: 'trendValue',
|
||||||
category: 'Trends',
|
category: 'Trends',
|
||||||
|
|||||||
Reference in New Issue
Block a user