Merge branch 'develop'
This commit is contained in:
@@ -147,6 +147,13 @@ export default class DataProcessor {
|
|||||||
return DataProcessor.groupBy(interval, groupByCallback, datapoints);
|
return DataProcessor.groupBy(interval, groupByCallback, datapoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static aggregateByWrapper(interval, aggregateFunc, datapoints) {
|
||||||
|
// Flatten all points in frame and then just use groupBy()
|
||||||
|
var flattenedPoints = _.flatten(datapoints, true);
|
||||||
|
var groupByCallback = DataProcessor.aggregationFunctions[aggregateFunc];
|
||||||
|
return DataProcessor.groupBy(interval, groupByCallback, flattenedPoints);
|
||||||
|
}
|
||||||
|
|
||||||
static aggregateWrapper(groupByCallback, interval, datapoints) {
|
static aggregateWrapper(groupByCallback, interval, datapoints) {
|
||||||
var flattenedPoints = _.flatten(datapoints, true);
|
var flattenedPoints = _.flatten(datapoints, true);
|
||||||
return DataProcessor.groupBy(interval, groupByCallback, flattenedPoints);
|
return DataProcessor.groupBy(interval, groupByCallback, flattenedPoints);
|
||||||
@@ -164,6 +171,7 @@ export default class DataProcessor {
|
|||||||
static get metricFunctions() {
|
static get metricFunctions() {
|
||||||
return {
|
return {
|
||||||
groupBy: this.groupByWrapper,
|
groupBy: this.groupByWrapper,
|
||||||
|
aggregateBy: this.aggregateByWrapper,
|
||||||
average: _.partial(this.aggregateWrapper, this.AVERAGE),
|
average: _.partial(this.aggregateWrapper, this.AVERAGE),
|
||||||
min: _.partial(this.aggregateWrapper, this.MIN),
|
min: _.partial(this.aggregateWrapper, this.MIN),
|
||||||
max: _.partial(this.aggregateWrapper, this.MAX),
|
max: _.partial(this.aggregateWrapper, this.MAX),
|
||||||
|
|||||||
@@ -73,6 +73,16 @@ addFuncDef({
|
|||||||
defaultParams: ['1m'],
|
defaultParams: ['1m'],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addFuncDef({
|
||||||
|
name: 'aggregateBy',
|
||||||
|
category: 'Aggregate',
|
||||||
|
params: [
|
||||||
|
{ name: 'interval', type: 'string' },
|
||||||
|
{ name: 'function', type: 'string', options: ['avg', 'min', 'max', 'median'] }
|
||||||
|
],
|
||||||
|
defaultParams: ['1m', 'avg'],
|
||||||
|
});
|
||||||
|
|
||||||
addFuncDef({
|
addFuncDef({
|
||||||
name: 'trendValue',
|
name: 'trendValue',
|
||||||
category: 'Trends',
|
category: 'Trends',
|
||||||
|
|||||||
@@ -12,14 +12,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- IT Service editor -->
|
<!-- IT Service editor -->
|
||||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == 1">
|
<div class="gf-form-inline" ng-show="ctrl.target.mode == 1">
|
||||||
<div class="gf-form max-width-20">
|
<div class="gf-form max-width-20">
|
||||||
<label class="gf-form-label width-7">IT Service</label>
|
<label class="gf-form-label query-keyword width-7">IT Service</label>
|
||||||
<div class="gf-form-select-wrapper max-width-20">
|
<div class="gf-form-select-wrapper max-width-20">
|
||||||
<select class="gf-form-input"
|
<select class="gf-form-input"
|
||||||
ng-change="ctrl.selectITService()"
|
ng-change="ctrl.selectITService()"
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label">IT service property</label>
|
<label class="gf-form-label query-keyword">IT service property</label>
|
||||||
<div class="gf-form-select-wrapper">
|
<div class="gf-form-select-wrapper">
|
||||||
<select class="gf-form-input"
|
<select class="gf-form-input"
|
||||||
ng-change="ctrl.selectITService()"
|
ng-change="ctrl.selectITService()"
|
||||||
@@ -42,14 +42,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-hide="ctrl.target.mode == 1">
|
<div class="gf-form-inline" ng-hide="ctrl.target.mode == 1">
|
||||||
<!-- Select Group -->
|
<!-- Select Group -->
|
||||||
<div class="gf-form max-width-20">
|
<div class="gf-form max-width-20">
|
||||||
<label class="gf-form-label width-7">Group</label>
|
<label class="gf-form-label query-keyword width-7">Group</label>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
ng-model="ctrl.target.group.filter"
|
ng-model="ctrl.target.group.filter"
|
||||||
bs-typeahead="ctrl.getGroupNames"
|
bs-typeahead="ctrl.getGroupNames"
|
||||||
@@ -64,7 +64,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Select Host -->
|
<!-- Select Host -->
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label width-7">Host</label>
|
<label class="gf-form-label query-keyword width-7">Host</label>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
ng-model="ctrl.target.host.filter"
|
ng-model="ctrl.target.host.filter"
|
||||||
bs-typeahead="ctrl.getHostNames"
|
bs-typeahead="ctrl.getHostNames"
|
||||||
@@ -78,19 +78,15 @@
|
|||||||
}">
|
}">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<gf-form-switch class="gf-form" ng-hide="ctrl.target.mode == 2"
|
|
||||||
label="Show disabled items" checked="ctrl.target.showDisabledItems" on-change="ctrl.onTargetBlur()">
|
|
||||||
</gf-form-switch>
|
|
||||||
|
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-inline" ng-hide="ctrl.target.mode == 1">
|
<div class="gf-form-inline" ng-hide="ctrl.target.mode == 1">
|
||||||
<!-- Select Application -->
|
<!-- Select Application -->
|
||||||
<div class="gf-form max-width-20">
|
<div class="gf-form max-width-20">
|
||||||
<label class="gf-form-label width-7">Application</label>
|
<label class="gf-form-label query-keyword width-7">Application</label>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
ng-model="ctrl.target.application.filter"
|
ng-model="ctrl.target.application.filter"
|
||||||
bs-typeahead="ctrl.getApplicationNames"
|
bs-typeahead="ctrl.getApplicationNames"
|
||||||
@@ -106,7 +102,7 @@
|
|||||||
|
|
||||||
<!-- Select Item -->
|
<!-- Select Item -->
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label width-7">Item</label>
|
<label class="gf-form-label query-keyword width-7">Item</label>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
ng-model="ctrl.target.item.filter"
|
ng-model="ctrl.target.item.filter"
|
||||||
bs-typeahead="ctrl.getItemNames"
|
bs-typeahead="ctrl.getItemNames"
|
||||||
@@ -119,21 +115,35 @@
|
|||||||
'zbx-regex': ctrl.isRegex(ctrl.target.item.filter)
|
'zbx-regex': ctrl.isRegex(ctrl.target.item.filter)
|
||||||
}">
|
}">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="gf-form gf-form--grow">
|
||||||
|
<label class="gf-form-label gf-form-label--grow">
|
||||||
|
<a ng-click="ctrl.toggleQueryOptions()">
|
||||||
|
<i class="fa fa-caret-down" ng-show="ctrl.showQueryOptions"></i>
|
||||||
|
<i class="fa fa-caret-right" ng-hide="ctrl.showQueryOptions"></i>
|
||||||
|
{{ctrl.queryOptionsText}}
|
||||||
|
</a>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Metric processing functions -->
|
||||||
|
<div class="gf-form-inline" ng-hide="ctrl.target.mode">
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<label class="gf-form-label">Options</label>
|
<label class="gf-form-label query-keyword width-7">Functions</label>
|
||||||
<div ng-repeat="func in ctrl.target.functions" class="gf-form-label query-part" metric-function-editor></div>
|
<div ng-repeat="func in ctrl.target.functions" class="gf-form-label query-part" metric-function-editor></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form dropdown" add-metric-function>
|
<div class="gf-form dropdown" add-metric-function>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<div class="gf-form-label gf-form-label--grow"></div>
|
<div class="gf-form-label gf-form-label--grow"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Text mode options -->
|
||||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == 2">
|
<div class="gf-form-inline" ng-show="ctrl.target.mode == 2">
|
||||||
<!-- Text metric regex -->
|
<!-- Text metric regex -->
|
||||||
<div class="gf-form max-width-20">
|
<div class="gf-form max-width-20">
|
||||||
<label class="gf-form-label width-7">Text filter</label>
|
<label class="gf-form-label query-keyword width-7">Text filter</label>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
class="gf-form-input"
|
class="gf-form-input"
|
||||||
ng-model="ctrl.target.textFilter"
|
ng-model="ctrl.target.textFilter"
|
||||||
@@ -143,7 +153,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<gf-form-switch class="gf-form" label="Use capture groups" checked="ctrl.target.useCaptureGroups" on-change="ctrl.onTargetBlur()">
|
<gf-form-switch class="gf-form" label="Use capture groups" checked="ctrl.target.useCaptureGroups" on-change="ctrl.onTargetBlur()">
|
||||||
</gf-form-switch>
|
</gf-form-switch>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Query options -->
|
||||||
|
<div class="gf-form-group" ng-if="ctrl.showQueryOptions">
|
||||||
|
<div class="gf-form offset-width-7">
|
||||||
|
<gf-form-switch class="gf-form" ng-hide="ctrl.target.mode == 2"
|
||||||
|
label="Show disabled items"
|
||||||
|
checked="ctrl.target.options.showDisabledItems"
|
||||||
|
on-change="ctrl.onQueryOptionChange()">
|
||||||
|
</gf-form-switch>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</query-editor-row>
|
</query-editor-row>
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ export class ZabbixQueryController extends QueryCtrl {
|
|||||||
this.templateSrv = templateSrv;
|
this.templateSrv = templateSrv;
|
||||||
|
|
||||||
this.editorModes = {
|
this.editorModes = {
|
||||||
0: {value: 'num', text: 'Numeric metrics', mode: 0},
|
0: {value: 'num', text: 'Metrics', mode: 0},
|
||||||
1: {value: 'itservice', text: 'IT Services', mode: 1},
|
1: {value: 'itservice', text: 'IT Services', mode: 1},
|
||||||
2: {value: 'text', text: 'Text metrics', mode: 2}
|
2: {value: 'text', text: 'Text', mode: 2}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Map functions for bs-typeahead
|
// Map functions for bs-typeahead
|
||||||
@@ -48,7 +48,8 @@ export class ZabbixQueryController extends QueryCtrl {
|
|||||||
|
|
||||||
var scopeDefaults = {
|
var scopeDefaults = {
|
||||||
metric: {},
|
metric: {},
|
||||||
oldTarget: _.cloneDeep(this.target)
|
oldTarget: _.cloneDeep(this.target),
|
||||||
|
queryOptionsText: this.renderQueryOptionsText()
|
||||||
};
|
};
|
||||||
_.defaults(this, scopeDefaults);
|
_.defaults(this, scopeDefaults);
|
||||||
|
|
||||||
@@ -60,6 +61,9 @@ export class ZabbixQueryController extends QueryCtrl {
|
|||||||
application: { filter: "" },
|
application: { filter: "" },
|
||||||
item: { filter: "" },
|
item: { filter: "" },
|
||||||
functions: [],
|
functions: [],
|
||||||
|
options: {
|
||||||
|
showDisabledItems: false
|
||||||
|
}
|
||||||
};
|
};
|
||||||
_.defaults(target, targetDefaults);
|
_.defaults(target, targetDefaults);
|
||||||
|
|
||||||
@@ -155,7 +159,7 @@ export class ZabbixQueryController extends QueryCtrl {
|
|||||||
return self.zabbix
|
return self.zabbix
|
||||||
.getItems(undefined, appids, itemtype)
|
.getItems(undefined, appids, itemtype)
|
||||||
.then(items => {
|
.then(items => {
|
||||||
if (!self.target.showDisabledItems) {
|
if (!self.target.options.showDisabledItems) {
|
||||||
items = _.filter(items, {'status': '0'});
|
items = _.filter(items, {'status': '0'});
|
||||||
}
|
}
|
||||||
self.metric.itemList = items;
|
self.metric.itemList = items;
|
||||||
@@ -168,7 +172,7 @@ export class ZabbixQueryController extends QueryCtrl {
|
|||||||
return self.zabbix
|
return self.zabbix
|
||||||
.getItems(hostids, undefined, itemtype)
|
.getItems(hostids, undefined, itemtype)
|
||||||
.then(items => {
|
.then(items => {
|
||||||
if (!self.target.showDisabledItems) {
|
if (!self.target.options.showDisabledItems) {
|
||||||
items = _.filter(items, {'status': '0'});
|
items = _.filter(items, {'status': '0'});
|
||||||
}
|
}
|
||||||
self.metric.itemList = items;
|
self.metric.itemList = items;
|
||||||
@@ -257,6 +261,34 @@ export class ZabbixQueryController extends QueryCtrl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleQueryOptions() {
|
||||||
|
this.showQueryOptions = !this.showQueryOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
onQueryOptionChange() {
|
||||||
|
this.queryOptionsText = this.renderQueryOptionsText();
|
||||||
|
this.onTargetBlur();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderQueryOptionsText() {
|
||||||
|
var optionsMap = {
|
||||||
|
showDisabledItems: "Show disabled items"
|
||||||
|
};
|
||||||
|
var options = [];
|
||||||
|
_.forOwn(this.target.options, (value, key) => {
|
||||||
|
if (value) {
|
||||||
|
if (value === true) {
|
||||||
|
// Show only option name (if enabled) for boolean options
|
||||||
|
options.push(optionsMap[key]);
|
||||||
|
} else {
|
||||||
|
// Show "option = value" for another options
|
||||||
|
options.push(optionsMap[key] + " = " + value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return "Options: " + options.join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch query editor to specified mode.
|
* Switch query editor to specified mode.
|
||||||
* Modes:
|
* Modes:
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
{"name": "Metric Editor", "path": "img/screenshot-metric_editor.png"},
|
{"name": "Metric Editor", "path": "img/screenshot-metric_editor.png"},
|
||||||
{"name": "Triggers", "path": "img/screenshot-triggers.png"}
|
{"name": "Triggers", "path": "img/screenshot-triggers.png"}
|
||||||
],
|
],
|
||||||
"version": "3.0.0-beta7",
|
"version": "3.0.0-beta8",
|
||||||
"updated": "2016-04-14"
|
"updated": "2016-04-30"
|
||||||
},
|
},
|
||||||
|
|
||||||
"includes": [
|
"includes": [
|
||||||
|
|||||||
Reference in New Issue
Block a user