grafana/public/app/plugins/datasource/graphite/gfunc.ts
2017-12-19 16:06:54 +01:00

1172 lines
23 KiB
TypeScript

import _ from "lodash";
import $ from "jquery";
import { isVersionGtOrEq } from "app/core/utils/version";
var index = [];
var categories = {
Combine: [],
Transform: [],
Calculate: [],
Filter: [],
Special: []
};
function addFuncDef(funcDef) {
funcDef.params = funcDef.params || [];
funcDef.defaultParams = funcDef.defaultParams || [];
if (funcDef.category) {
funcDef.category.push(funcDef);
}
index[funcDef.name] = funcDef;
index[funcDef.shortName || funcDef.name] = funcDef;
}
var optionalSeriesRefArgs = [
{ name: "other", type: "value_or_series", optional: true },
{ name: "other", type: "value_or_series", optional: true },
{ name: "other", type: "value_or_series", optional: true },
{ name: "other", type: "value_or_series", optional: true },
{ name: "other", type: "value_or_series", optional: true }
];
addFuncDef({
name: "scaleToSeconds",
category: categories.Transform,
params: [{ name: "seconds", type: "int" }],
defaultParams: [1]
});
addFuncDef({
name: "perSecond",
category: categories.Transform,
params: [{ name: "max value", type: "int", optional: true }],
defaultParams: []
});
addFuncDef({
name: "holtWintersForecast",
category: categories.Calculate
});
addFuncDef({
name: "holtWintersConfidenceBands",
category: categories.Calculate,
params: [{ name: "delta", type: "int" }],
defaultParams: [3]
});
addFuncDef({
name: "holtWintersAberration",
category: categories.Calculate,
params: [{ name: "delta", type: "int" }],
defaultParams: [3]
});
addFuncDef({
name: "nPercentile",
category: categories.Calculate,
params: [{ name: "Nth percentile", type: "int" }],
defaultParams: [95]
});
addFuncDef({
name: "diffSeries",
params: optionalSeriesRefArgs,
defaultParams: ["#A"],
category: categories.Calculate
});
addFuncDef({
name: "stddevSeries",
params: optionalSeriesRefArgs,
defaultParams: [""],
category: categories.Calculate
});
addFuncDef({
name: "divideSeries",
params: optionalSeriesRefArgs,
defaultParams: ["#A"],
category: categories.Calculate
});
addFuncDef({
name: "multiplySeries",
params: optionalSeriesRefArgs,
defaultParams: ["#A"],
category: categories.Calculate
});
addFuncDef({
name: "asPercent",
params: optionalSeriesRefArgs,
defaultParams: ["#A"],
category: categories.Calculate
});
addFuncDef({
name: "group",
params: optionalSeriesRefArgs,
defaultParams: ["#A", "#B"],
category: categories.Combine
});
addFuncDef({
name: "sumSeries",
shortName: "sum",
category: categories.Combine,
params: optionalSeriesRefArgs,
defaultParams: [""]
});
addFuncDef({
name: "averageSeries",
shortName: "avg",
category: categories.Combine,
params: optionalSeriesRefArgs,
defaultParams: [""]
});
addFuncDef({
name: "rangeOfSeries",
category: categories.Combine
});
addFuncDef({
name: "percentileOfSeries",
category: categories.Combine,
params: [
{ name: "n", type: "int" },
{ name: "interpolate", type: "boolean", options: ["true", "false"] }
],
defaultParams: [95, "false"]
});
addFuncDef({
name: "sumSeriesWithWildcards",
category: categories.Combine,
params: [
{ name: "node", type: "int" },
{ name: "node", type: "int", optional: true },
{ name: "node", type: "int", optional: true },
{ name: "node", type: "int", optional: true }
],
defaultParams: [3]
});
addFuncDef({
name: "maxSeries",
shortName: "max",
category: categories.Combine
});
addFuncDef({
name: "minSeries",
shortName: "min",
category: categories.Combine
});
addFuncDef({
name: "averageSeriesWithWildcards",
category: categories.Combine,
params: [
{ name: "node", type: "int" },
{ name: "node", type: "int", optional: true }
],
defaultParams: [3]
});
addFuncDef({
name: "alias",
category: categories.Special,
params: [{ name: "alias", type: "string" }],
defaultParams: ["alias"]
});
addFuncDef({
name: "aliasSub",
category: categories.Special,
params: [
{ name: "search", type: "string" },
{ name: "replace", type: "string" }
],
defaultParams: ["", "\\1"]
});
addFuncDef({
name: "stacked",
category: categories.Special,
params: [{ name: "stack", type: "string" }],
defaultParams: ["stacked"]
});
addFuncDef({
name: "consolidateBy",
category: categories.Special,
params: [
{
name: "function",
type: "string",
options: ["sum", "average", "min", "max"]
}
],
defaultParams: ["max"]
});
addFuncDef({
name: "cumulative",
category: categories.Special,
params: [],
defaultParams: []
});
addFuncDef({
name: "groupByNode",
category: categories.Special,
params: [
{
name: "node",
type: "int",
options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
},
{
name: "function",
type: "string",
options: ["sum", "avg", "maxSeries"]
}
],
defaultParams: [3, "sum"]
});
addFuncDef({
name: "aliasByNode",
category: categories.Special,
params: [
{
name: "node",
type: "int",
options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
},
{
name: "node",
type: "int",
options: [0, -1, -2, -3, -4, -5, -6, -7],
optional: true
},
{
name: "node",
type: "int",
options: [0, -1, -2, -3, -4, -5, -6, -7],
optional: true
},
{
name: "node",
type: "int",
options: [0, -1, -2, -3, -4, -5, -6, -7],
optional: true
}
],
defaultParams: [3]
});
addFuncDef({
name: "substr",
category: categories.Special,
params: [
{
name: "start",
type: "int",
options: [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
},
{
name: "stop",
type: "int",
options: [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
}
],
defaultParams: [0, 0]
});
addFuncDef({
name: "sortByName",
category: categories.Special,
params: [
{
name: "natural",
type: "boolean",
options: ["true", "false"],
optional: true
}
],
defaultParams: ["false"]
});
addFuncDef({
name: "sortByMaxima",
category: categories.Special
});
addFuncDef({
name: "sortByMinima",
category: categories.Special
});
addFuncDef({
name: "sortByTotal",
category: categories.Special
});
addFuncDef({
name: "aliasByMetric",
category: categories.Special
});
addFuncDef({
name: "randomWalk",
fake: true,
category: categories.Special,
params: [{ name: "name", type: "string" }],
defaultParams: ["randomWalk"]
});
addFuncDef({
name: "countSeries",
category: categories.Special
});
addFuncDef({
name: "constantLine",
category: categories.Special,
params: [{ name: "value", type: "int" }],
defaultParams: [10]
});
addFuncDef({
name: "cactiStyle",
category: categories.Special
});
addFuncDef({
name: "keepLastValue",
category: categories.Special,
params: [{ name: "n", type: "int" }],
defaultParams: [100]
});
addFuncDef({
name: "changed",
category: categories.Special,
params: [],
defaultParams: []
});
addFuncDef({
name: "scale",
category: categories.Transform,
params: [{ name: "factor", type: "int" }],
defaultParams: [1]
});
addFuncDef({
name: "offset",
category: categories.Transform,
params: [{ name: "amount", type: "int" }],
defaultParams: [10]
});
addFuncDef({
name: "transformNull",
category: categories.Transform,
params: [{ name: "amount", type: "int" }],
defaultParams: [0]
});
addFuncDef({
name: "integral",
category: categories.Transform
});
addFuncDef({
name: "derivative",
category: categories.Transform
});
addFuncDef({
name: "nonNegativeDerivative",
category: categories.Transform,
params: [{ name: "max value or 0", type: "int", optional: true }],
defaultParams: [""]
});
addFuncDef({
name: "timeShift",
category: categories.Transform,
params: [
{
name: "amount",
type: "select",
options: ["1h", "6h", "12h", "1d", "2d", "7d", "14d", "30d"]
}
],
defaultParams: ["1d"]
});
addFuncDef({
name: "timeStack",
category: categories.Transform,
params: [
{
name: "timeShiftUnit",
type: "select",
options: ["1h", "6h", "12h", "1d", "2d", "7d", "14d", "30d"]
},
{ name: "timeShiftStart", type: "int" },
{ name: "timeShiftEnd", type: "int" }
],
defaultParams: ["1d", 0, 7]
});
addFuncDef({
name: "summarize",
category: categories.Transform,
params: [
{ name: "interval", type: "string" },
{
name: "func",
type: "select",
options: ["sum", "avg", "min", "max", "last"]
},
{
name: "alignToFrom",
type: "boolean",
optional: true,
options: ["false", "true"]
}
],
defaultParams: ["1h", "sum", "false"]
});
addFuncDef({
name: "smartSummarize",
category: categories.Transform,
params: [
{ name: "interval", type: "string" },
{
name: "func",
type: "select",
options: ["sum", "avg", "min", "max", "last"]
}
],
defaultParams: ["1h", "sum"]
});
addFuncDef({
name: "absolute",
category: categories.Transform
});
addFuncDef({
name: "hitcount",
category: categories.Transform,
params: [{ name: "interval", type: "string" }],
defaultParams: ["10s"]
});
addFuncDef({
name: "log",
category: categories.Transform,
params: [{ name: "base", type: "int" }],
defaultParams: ["10"]
});
addFuncDef({
name: "averageAbove",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [25]
});
addFuncDef({
name: "averageBelow",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [25]
});
addFuncDef({
name: "currentAbove",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [25]
});
addFuncDef({
name: "currentBelow",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [25]
});
addFuncDef({
name: "maximumAbove",
category: categories.Filter,
params: [{ name: "value", type: "int" }],
defaultParams: [0]
});
addFuncDef({
name: "maximumBelow",
category: categories.Filter,
params: [{ name: "value", type: "int" }],
defaultParams: [0]
});
addFuncDef({
name: "minimumAbove",
category: categories.Filter,
params: [{ name: "value", type: "int" }],
defaultParams: [0]
});
addFuncDef({
name: "minimumBelow",
category: categories.Filter,
params: [{ name: "value", type: "int" }],
defaultParams: [0]
});
addFuncDef({
name: "limit",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "mostDeviant",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [10]
});
addFuncDef({
name: "exclude",
category: categories.Filter,
params: [{ name: "exclude", type: "string" }],
defaultParams: ["exclude"]
});
addFuncDef({
name: "highestCurrent",
category: categories.Filter,
params: [{ name: "count", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "highestMax",
category: categories.Filter,
params: [{ name: "count", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "lowestCurrent",
category: categories.Filter,
params: [{ name: "count", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "movingAverage",
category: categories.Filter,
params: [
{
name: "windowSize",
type: "int_or_interval",
options: ["5", "7", "10", "5min", "10min", "30min", "1hour"]
}
],
defaultParams: [10]
});
addFuncDef({
name: "movingMedian",
category: categories.Filter,
params: [
{
name: "windowSize",
type: "int_or_interval",
options: ["5", "7", "10", "5min", "10min", "30min", "1hour"]
}
],
defaultParams: ["5"]
});
addFuncDef({
name: "stdev",
category: categories.Filter,
params: [{ name: "n", type: "int" }, { name: "tolerance", type: "int" }],
defaultParams: [5, 0.1]
});
addFuncDef({
name: "highestAverage",
category: categories.Filter,
params: [{ name: "count", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "lowestAverage",
category: categories.Filter,
params: [{ name: "count", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "removeAbovePercentile",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "removeAboveValue",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "removeBelowPercentile",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "removeBelowValue",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [5]
});
addFuncDef({
name: "useSeriesAbove",
category: categories.Filter,
params: [
{ name: "value", type: "int" },
{ name: "search", type: "string" },
{ name: "replace", type: "string" }
],
defaultParams: [0, "search", "replace"]
});
////////////////////
// Graphite 1.0.x //
////////////////////
addFuncDef({
name: "aggregateLine",
category: categories.Combine,
params: [
{
name: "func",
type: "select",
options: ["sum", "avg", "min", "max", "last"]
}
],
defaultParams: ["avg"],
version: "1.0"
});
addFuncDef({
name: "averageOutsidePercentile",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [95],
version: "1.0"
});
addFuncDef({
name: "delay",
category: categories.Transform,
params: [{ name: "steps", type: "int" }],
defaultParams: [1],
version: "1.0"
});
addFuncDef({
name: "exponentialMovingAverage",
category: categories.Calculate,
params: [
{
name: "windowSize",
type: "int_or_interval",
options: ["5", "7", "10", "5min", "10min", "30min", "1hour"]
}
],
defaultParams: [10],
version: "1.0"
});
addFuncDef({
name: "fallbackSeries",
category: categories.Special,
params: [{ name: "fallback", type: "string" }],
defaultParams: ["constantLine(0)"],
version: "1.0"
});
addFuncDef({
name: "grep",
category: categories.Filter,
params: [{ name: "grep", type: "string" }],
defaultParams: ["grep"],
version: "1.0"
});
addFuncDef({
name: "groupByNodes",
category: categories.Special,
params: [
{
name: "function",
type: "string",
options: ["sum", "avg", "maxSeries"]
},
{
name: "node",
type: "int",
options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
},
{
name: "node",
type: "int",
options: [0, -1, -2, -3, -4, -5, -6, -7],
optional: true
},
{
name: "node",
type: "int",
options: [0, -1, -2, -3, -4, -5, -6, -7],
optional: true
},
{
name: "node",
type: "int",
options: [0, -1, -2, -3, -4, -5, -6, -7],
optional: true
}
],
defaultParams: ["sum", 3],
version: "1.0"
});
addFuncDef({
name: "integralByInterval",
category: categories.Transform,
params: [
{
name: "intervalUnit",
type: "select",
options: ["1h", "6h", "12h", "1d", "2d", "7d", "14d", "30d"]
}
],
defaultParams: ["1d"],
version: "1.0"
});
addFuncDef({
name: "interpolate",
category: categories.Transform,
params: [{ name: "limit", type: "int", optional: true }],
defaultParams: [],
version: "1.0"
});
addFuncDef({
name: "invert",
category: categories.Transform,
version: "1.0"
});
addFuncDef({
name: "isNonNull",
category: categories.Combine,
version: "1.0"
});
addFuncDef({
name: "linearRegression",
category: categories.Calculate,
params: [
{
name: "startSourceAt",
type: "select",
options: ["-1h", "-6h", "-12h", "-1d", "-2d", "-7d", "-14d", "-30d"],
optional: true
},
{
name: "endSourceAt",
type: "select",
options: ["-1h", "-6h", "-12h", "-1d", "-2d", "-7d", "-14d", "-30d"],
optional: true
}
],
defaultParams: [],
version: "1.0"
});
addFuncDef({
name: "mapSeries",
shortName: "map",
params: [{ name: "node", type: "int" }],
defaultParams: [3],
category: categories.Combine,
version: "1.0"
});
addFuncDef({
name: "movingMin",
category: categories.Calculate,
params: [
{
name: "windowSize",
type: "int_or_interval",
options: ["5", "7", "10", "5min", "10min", "30min", "1hour"]
}
],
defaultParams: [10],
version: "1.0"
});
addFuncDef({
name: "movingMax",
category: categories.Calculate,
params: [
{
name: "windowSize",
type: "int_or_interval",
options: ["5", "7", "10", "5min", "10min", "30min", "1hour"]
}
],
defaultParams: [10],
version: "1.0"
});
addFuncDef({
name: "movingSum",
category: categories.Calculate,
params: [
{
name: "windowSize",
type: "int_or_interval",
options: ["5", "7", "10", "5min", "10min", "30min", "1hour"]
}
],
defaultParams: [10],
version: "1.0"
});
addFuncDef({
name: "multiplySeriesWithWildcards",
category: categories.Calculate,
params: [
{
name: "position",
type: "int",
options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
},
{
name: "position",
type: "int",
options: [0, -1, -2, -3, -4, -5, -6, -7],
optional: true
},
{
name: "position",
type: "int",
options: [0, -1, -2, -3, -4, -5, -6, -7],
optional: true
},
{
name: "position",
type: "int",
options: [0, -1, -2, -3, -4, -5, -6, -7],
optional: true
}
],
defaultParams: [2],
version: "1.0"
});
addFuncDef({
name: "offsetToZero",
category: categories.Transform,
version: "1.0"
});
addFuncDef({
name: "pow",
category: categories.Transform,
params: [{ name: "factor", type: "int" }],
defaultParams: [10],
version: "1.0"
});
addFuncDef({
name: "powSeries",
category: categories.Transform,
params: optionalSeriesRefArgs,
defaultParams: [""],
version: "1.0"
});
addFuncDef({
name: "reduceSeries",
shortName: "reduce",
params: [
{
name: "function",
type: "string",
options: ["asPercent", "diffSeries", "divideSeries"]
},
{
name: "reduceNode",
type: "int",
options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
},
{ name: "reduceMatchers", type: "string" },
{ name: "reduceMatchers", type: "string" }
],
defaultParams: ["asPercent", 2, "used_bytes", "total_bytes"],
category: categories.Combine,
version: "1.0"
});
addFuncDef({
name: "removeBetweenPercentile",
category: categories.Filter,
params: [{ name: "n", type: "int" }],
defaultParams: [95],
version: "1.0"
});
addFuncDef({
name: "removeEmptySeries",
category: categories.Filter,
version: "1.0"
});
addFuncDef({
name: "squareRoot",
category: categories.Transform,
version: "1.0"
});
addFuncDef({
name: "timeSlice",
category: categories.Transform,
params: [
{
name: "startSliceAt",
type: "select",
options: ["-1h", "-6h", "-12h", "-1d", "-2d", "-7d", "-14d", "-30d"]
},
{
name: "endSliceAt",
type: "select",
options: ["-1h", "-6h", "-12h", "-1d", "-2d", "-7d", "-14d", "-30d"],
optional: true
}
],
defaultParams: ["-1h"],
version: "1.0"
});
addFuncDef({
name: "weightedAverage",
category: categories.Filter,
params: [
{ name: "other", type: "value_or_series", optional: true },
{
name: "node",
type: "int",
options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
}
],
defaultParams: ["#A", 4],
version: "1.0"
});
addFuncDef({
name: "seriesByTag",
category: categories.Special,
params: [
{ name: "tagExpression", type: "string" },
{ name: "tagExpression", type: "string", optional: true },
{ name: "tagExpression", type: "string", optional: true },
{ name: "tagExpression", type: "string", optional: true }
],
version: "1.1"
});
addFuncDef({
name: "groupByTags",
category: categories.Special,
params: [
{
name: "function",
type: "string",
options: ["sum", "avg", "maxSeries"]
},
{ name: "tag", type: "string" },
{ name: "tag", type: "string", optional: true },
{ name: "tag", type: "string", optional: true },
{ name: "tag", type: "string", optional: true }
],
defaultParams: ["sum", "tag"],
version: "1.1"
});
addFuncDef({
name: "aliasByTags",
category: categories.Special,
params: [
{ name: "tag", type: "string" },
{ name: "tag", type: "string", optional: true },
{ name: "tag", type: "string", optional: true },
{ name: "tag", type: "string", optional: true }
],
defaultParams: ["tag"],
version: "1.1"
});
_.each(categories, function(funcList, catName) {
categories[catName] = _.sortBy(funcList, "name");
});
function isVersionRelatedFunction(func, graphiteVersion) {
return isVersionGtOrEq(graphiteVersion, func.version) || !func.version;
}
export class FuncInstance {
def: any;
params: any;
text: any;
added: boolean;
constructor(funcDef, options) {
this.def = funcDef;
this.params = [];
if (options && options.withDefaultParams) {
this.params = funcDef.defaultParams.slice(0);
}
this.updateText();
}
render(metricExp) {
var str = this.def.name + "(";
var parameters = _.map(
this.params,
function(value, index) {
var paramType = this.def.params[index].type;
if (
paramType === "int" ||
paramType === "value_or_series" ||
paramType === "boolean"
) {
return value;
} else if (paramType === "int_or_interval" && $.isNumeric(value)) {
return value;
}
return "'" + value + "'";
}.bind(this)
);
if (metricExp) {
parameters.unshift(metricExp);
}
return str + parameters.join(", ") + ")";
}
_hasMultipleParamsInString(strValue, index) {
if (strValue.indexOf(",") === -1) {
return false;
}
return this.def.params[index + 1] && this.def.params[index + 1].optional;
}
updateParam(strValue, index) {
// handle optional parameters
// if string contains ',' and next param is optional, split and update both
if (this._hasMultipleParamsInString(strValue, index)) {
_.each(
strValue.split(","),
function(partVal, idx) {
this.updateParam(partVal.trim(), index + idx);
}.bind(this)
);
return;
}
if (strValue === "" && this.def.params[index].optional) {
this.params.splice(index, 1);
} else {
this.params[index] = strValue;
}
this.updateText();
}
updateText() {
if (this.params.length === 0) {
this.text = this.def.name + "()";
return;
}
var text = this.def.name + "(";
text += this.params.join(", ");
text += ")";
this.text = text;
}
}
export default {
createFuncInstance: function(funcDef, options?) {
if (_.isString(funcDef)) {
if (!index[funcDef]) {
throw { message: "Method not found " + name };
}
funcDef = index[funcDef];
}
return new FuncInstance(funcDef, options);
},
getFuncDef: function(name) {
return index[name];
},
getCategories: function(graphiteVersion) {
var filteredCategories: any = {};
_.each(categories, function(functions, category) {
var filteredFuncs = _.filter(functions, function(func) {
return isVersionRelatedFunction(func, graphiteVersion);
});
if (filteredFuncs.length) {
filteredCategories[category] = filteredFuncs;
}
});
return filteredCategories;
}
};