mirror of
https://github.com/grafana/grafana.git
synced 2025-01-17 20:13:35 -06:00
change: more work on changing default group by time interval to min interval setting
This commit is contained in:
parent
e8e1f1bc6d
commit
07e192ff47
@ -11,12 +11,10 @@ type DataSourcePlugin struct {
|
|||||||
Annotations bool `json:"annotations"`
|
Annotations bool `json:"annotations"`
|
||||||
Metrics bool `json:"metrics"`
|
Metrics bool `json:"metrics"`
|
||||||
Alerting bool `json:"alerting"`
|
Alerting bool `json:"alerting"`
|
||||||
MinInterval bool `json:"minInterval,omitempty"`
|
QueryOptions map[string]bool `json:"queryOptions,omitempty"`
|
||||||
CacheTimeout bool `json:"cacheTimeout,omitempty"`
|
|
||||||
MaxDataPoints bool `json:"maxDataPoints,omitempty"`
|
|
||||||
BuiltIn bool `json:"builtIn,omitempty"`
|
BuiltIn bool `json:"builtIn,omitempty"`
|
||||||
Mixed bool `json:"mixed,omitempty"`
|
Mixed bool `json:"mixed,omitempty"`
|
||||||
HasHelp bool `json:"hasHelp,omitempty"`
|
HasQueryHelp bool `json:"hasQueryHelp,omitempty"`
|
||||||
|
|
||||||
Routes []*AppPluginRoute `json:"-"`
|
Routes []*AppPluginRoute `json:"-"`
|
||||||
}
|
}
|
||||||
@ -31,12 +29,12 @@ func (p *DataSourcePlugin) Load(decoder *json.Decoder, pluginDir string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// look for help markdown
|
// look for help markdown
|
||||||
helpPath := filepath.Join(p.PluginDir, "HELP.md")
|
helpPath := filepath.Join(p.PluginDir, "QUERY_HELP.md")
|
||||||
if _, err := os.Stat(helpPath); os.IsNotExist(err) {
|
if _, err := os.Stat(helpPath); os.IsNotExist(err) {
|
||||||
helpPath = filepath.Join(p.PluginDir, "help.md")
|
helpPath = filepath.Join(p.PluginDir, "query_help.md")
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(helpPath); err == nil {
|
if _, err := os.Stat(helpPath); err == nil {
|
||||||
p.HasHelp = true
|
p.HasQueryHelp = true
|
||||||
}
|
}
|
||||||
|
|
||||||
DataSources[p.Id] = p
|
DataSources[p.Id] = p
|
||||||
|
@ -163,22 +163,16 @@ function($, _) {
|
|||||||
ms: 0.001
|
ms: 0.001
|
||||||
};
|
};
|
||||||
|
|
||||||
kbn.calculateInterval = function(range, resolution, userInterval) {
|
kbn.calculateInterval = function(range, resolution, lowLimitInterval) {
|
||||||
var lowLimitMs = 1; // 1 millisecond default low limit
|
var lowLimitMs = 1; // 1 millisecond default low limit
|
||||||
var intervalMs, lowLimitInterval;
|
var intervalMs;
|
||||||
|
|
||||||
if (userInterval) {
|
if (lowLimitInterval) {
|
||||||
if (userInterval[0] === '>') {
|
if (lowLimitInterval[0] === '>') {
|
||||||
lowLimitInterval = userInterval.slice(1);
|
lowLimitInterval = lowLimitInterval.slice(1);
|
||||||
|
}
|
||||||
lowLimitMs = kbn.interval_to_ms(lowLimitInterval);
|
lowLimitMs = kbn.interval_to_ms(lowLimitInterval);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return {
|
|
||||||
intervalMs: kbn.interval_to_ms(userInterval),
|
|
||||||
interval: userInterval,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
intervalMs = kbn.round_interval((range.to.valueOf() - range.from.valueOf()) / resolution);
|
intervalMs = kbn.round_interval((range.to.valueOf() - range.from.valueOf()) / resolution);
|
||||||
if (lowLimitMs > intervalMs) {
|
if (lowLimitMs > intervalMs) {
|
||||||
|
@ -16,12 +16,10 @@ export class MetricsTabCtrl {
|
|||||||
addQueryDropdown: any;
|
addQueryDropdown: any;
|
||||||
queryTroubleshooterOpen: boolean;
|
queryTroubleshooterOpen: boolean;
|
||||||
helpOpen: boolean;
|
helpOpen: boolean;
|
||||||
hasHelp: boolean;
|
|
||||||
helpHtml: string;
|
|
||||||
hasMinInterval: boolean;
|
|
||||||
hasCacheTimeout: boolean;
|
|
||||||
hasMaxDataPoints: boolean;
|
|
||||||
optionsOpen: boolean;
|
optionsOpen: boolean;
|
||||||
|
hasQueryHelp: boolean;
|
||||||
|
helpHtml: string;
|
||||||
|
queryOptions: any;
|
||||||
|
|
||||||
/** @ngInject */
|
/** @ngInject */
|
||||||
constructor($scope, private $sce, private datasourceSrv, private backendSrv, private $timeout) {
|
constructor($scope, private $sce, private datasourceSrv, private backendSrv, private $timeout) {
|
||||||
@ -46,10 +44,8 @@ export class MetricsTabCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateDatasourceOptions() {
|
updateDatasourceOptions() {
|
||||||
this.hasHelp = this.current.meta.hasHelp;
|
this.hasQueryHelp = this.current.meta.hasQueryHelp;
|
||||||
this.hasMinInterval = this.current.meta.minInterval === true;
|
this.queryOptions = this.current.meta.queryOptions;
|
||||||
this.hasCacheTimeout = this.current.meta.cacheTimeout === true;
|
|
||||||
this.hasMaxDataPoints = this.current.meta.maxDataPoints === true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getOptions(includeBuiltin) {
|
getOptions(includeBuiltin) {
|
||||||
@ -89,7 +85,7 @@ export class MetricsTabCtrl {
|
|||||||
this.queryTroubleshooterOpen = false;
|
this.queryTroubleshooterOpen = false;
|
||||||
this.helpOpen = !this.helpOpen;
|
this.helpOpen = !this.helpOpen;
|
||||||
|
|
||||||
this.backendSrv.get(`/api/plugins/${this.current.meta.id}/markdown/help`).then(res => {
|
this.backendSrv.get(`/api/plugins/${this.current.meta.id}/markdown/query_help`).then(res => {
|
||||||
var md = new Remarkable();
|
var md = new Remarkable();
|
||||||
this.helpHtml = this.$sce.trustAsHtml(md.render(res));
|
this.helpHtml = this.$sce.trustAsHtml(md.render(res));
|
||||||
});
|
});
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
<div class="gf-form gf-form--grow">
|
<div class="gf-form gf-form--grow">
|
||||||
<label class="gf-form-label gf-form-label--grow"></label>
|
<label class="gf-form-label gf-form-label--grow"></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form" ng-if="ctrl.hasHelp">
|
<div class="gf-form" ng-if="ctrl.queryOptions">
|
||||||
<a class="gf-form-label" ng-click="ctrl.toggleOptions()">
|
<a class="gf-form-label" ng-click="ctrl.toggleOptions()">
|
||||||
<i class="fa fa-fw fa-caret-right" ng-hide="ctrl.optionsOpen"></i><i class="fa fa-fw fa-caret-down" ng-show="ctrl.optionsOpen"></i>Options
|
<i class="fa fa-fw fa-caret-right" ng-hide="ctrl.optionsOpen"></i><i class="fa fa-fw fa-caret-down" ng-show="ctrl.optionsOpen"></i>Options
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form" ng-if="ctrl.hasHelp">
|
<div class="gf-form" ng-if="ctrl.hasQueryHelp">
|
||||||
<button class="gf-form-label" ng-click="ctrl.toggleHelp()">
|
<button class="gf-form-label" ng-click="ctrl.toggleHelp()">
|
||||||
<i class="fa fa-fw fa-caret-right" ng-hide="ctrl.helpOpen"></i><i class="fa fa-fw fa-caret-down" ng-show="ctrl.helpOpen"></i>Help
|
<i class="fa fa-fw fa-caret-right" ng-hide="ctrl.helpOpen"></i><i class="fa fa-fw fa-caret-down" ng-show="ctrl.helpOpen"></i>Help
|
||||||
</button>
|
</button>
|
||||||
@ -33,8 +33,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="" ng-if="ctrl.optionsOpen">
|
<div ng-if="ctrl.optionsOpen">
|
||||||
<div class="gf-form gf-form--flex-end" ng-if="ctrl.hasMinInterval">
|
<div class="gf-form gf-form--flex-end" ng-if="ctrl.queryOptions.minInterval">
|
||||||
<label class="gf-form-label">Min auto interval</label>
|
<label class="gf-form-label">Min auto interval</label>
|
||||||
<input type="text" class="gf-form-input width-6" placeholder="1s" ng-model="ctrl.panel.interval" spellcheck="false" ng-model-onblur ng-change="ctrl.panelCtrl.refresh()" />
|
<input type="text" class="gf-form-input width-6" placeholder="1s" ng-model="ctrl.panel.interval" spellcheck="false" ng-model-onblur ng-change="ctrl.panelCtrl.refresh()" />
|
||||||
<info-popover mode="right-absolute">
|
<info-popover mode="right-absolute">
|
||||||
@ -43,7 +43,7 @@
|
|||||||
string and <code>$__interval_ms</code> for numeric variable that can be used in math expressions.
|
string and <code>$__interval_ms</code> for numeric variable that can be used in math expressions.
|
||||||
</info-popover>
|
</info-popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--flex-end" ng-if="ctrl.hasCacheTimeout">
|
<div class="gf-form gf-form--flex-end" ng-if="ctrl.queryOptions.cacheTimeout">
|
||||||
<label class="gf-form-label width-9">Cache timeout</label>
|
<label class="gf-form-label width-9">Cache timeout</label>
|
||||||
<input type="text" class="gf-form-input width-6" placeholder="60" ng-model="ctrl.panel.cacheTimeout" ng-model-onblur ng-change="ctrl.panelCtrl.refresh()" spellcheck="false" />
|
<input type="text" class="gf-form-input width-6" placeholder="60" ng-model="ctrl.panel.cacheTimeout" ng-model-onblur ng-change="ctrl.panelCtrl.refresh()" spellcheck="false" />
|
||||||
<info-popover mode="right-absolute">
|
<info-popover mode="right-absolute">
|
||||||
@ -51,7 +51,7 @@
|
|||||||
cache timeout. Specify a numeric value in seconds.
|
cache timeout. Specify a numeric value in seconds.
|
||||||
</info-popover>
|
</info-popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="gf-form gf-form--flex-end" ng-if="ctrl.hasMaxDataPoints">
|
<div class="gf-form gf-form--flex-end" ng-if="ctrl.queryOptions.maxDataPoints">
|
||||||
<label class="gf-form-label width-9">Max data points</label>
|
<label class="gf-form-label width-9">Max data points</label>
|
||||||
<input type="text" class="gf-form-input width-6" placeholder="auto" ng-model-onblur ng-change="ctrl.panelCtrl.refresh()" ng-model="ctrl.panel.maxDataPoints" spellcheck="false" />
|
<input type="text" class="gf-form-input width-6" placeholder="auto" ng-model-onblur ng-change="ctrl.panelCtrl.refresh()" ng-model="ctrl.panel.maxDataPoints" spellcheck="false" />
|
||||||
<info-popover mode="right-absolute">
|
<info-popover mode="right-absolute">
|
||||||
|
@ -54,7 +54,7 @@ export class IntervalVariable implements Variable {
|
|||||||
this.options.unshift({ text: 'auto', value: '$__auto_interval' });
|
this.options.unshift({ text: 'auto', value: '$__auto_interval' });
|
||||||
}
|
}
|
||||||
|
|
||||||
var res = kbn.calculateInterval(this.timeSrv.timeRange(), this.auto_count, (this.auto_min ? ">"+this.auto_min : null));
|
var res = kbn.calculateInterval(this.timeSrv.timeRange(), this.auto_count, this.auto_min);
|
||||||
this.templateSrv.setGrafanaVariable('$__auto_interval', res.interval);
|
this.templateSrv.setGrafanaVariable('$__auto_interval', res.interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,13 +25,14 @@
|
|||||||
<span class="gf-form-label width-9">Version</span>
|
<span class="gf-form-label width-9">Version</span>
|
||||||
<select class="gf-form-input gf-size-auto" ng-model="ctrl.current.jsonData.esVersion" ng-options="f.value as f.name for f in ctrl.esVersions"></select>
|
<select class="gf-form-input gf-size-auto" ng-model="ctrl.current.jsonData.esVersion" ng-options="f.value as f.name for f in ctrl.esVersions"></select>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="gf-form-inline">
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 class="page-heading">Default query settings</h3>
|
|
||||||
<div class="gf-form-group">
|
|
||||||
<div class="gf-form">
|
<div class="gf-form">
|
||||||
<span class="gf-form-label">Group by time interval</span>
|
<span class="gf-form-label width-9">Min interval</span>
|
||||||
<input class="gf-form-input max-width-9" type="text" ng-model="ctrl.current.jsonData.timeInterval" spellcheck='false' placeholder="example: >10s">
|
<input type="text" class="gf-form-input width-6" ng-model="ctrl.current.jsonData.timeInterval" spellcheck='false' placeholder="10s"></input>
|
||||||
|
<info-popover mode="right-absolute">
|
||||||
|
A lower limit for the auto group by time interval. Recommended to be set to write frequency,
|
||||||
|
for example <code>1m</code> if your data is written every minute.
|
||||||
|
</info-popover>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,8 +10,11 @@
|
|||||||
"metrics": true,
|
"metrics": true,
|
||||||
"alerting": true,
|
"alerting": true,
|
||||||
"annotations": true,
|
"annotations": true,
|
||||||
|
|
||||||
|
"queryOptions": {
|
||||||
"maxDataPoints": true,
|
"maxDataPoints": true,
|
||||||
"cacheTimeout": true,
|
"cacheTimeout": true
|
||||||
|
},
|
||||||
|
|
||||||
"info": {
|
"info": {
|
||||||
"author": {
|
"author": {
|
||||||
|
@ -24,10 +24,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gf-form-group">
|
<div class="gf-form-group">
|
||||||
<div class="gf-form max-width-21">
|
<div class="gf-form-inline">
|
||||||
<span class="gf-form-label">Default group by time</span>
|
<div class="gf-form">
|
||||||
<input type="text" class="gf-form-input width-6" ng-model="ctrl.current.jsonData.timeInterval"
|
<span class="gf-form-label">Min interval</span>
|
||||||
spellcheck='false' placeholder="example: >10s"></input>
|
<input type="text" class="gf-form-input width-6" ng-model="ctrl.current.jsonData.timeInterval" spellcheck='false' placeholder="10s"></input>
|
||||||
<i class="fa fa-question-circle" bs-tooltip="'Set a low limit by having a greater sign: example: >10s'" data-placement="right"></i>
|
<info-popover mode="right-absolute">
|
||||||
|
A lower limit for the auto group by time interval. Recommended to be set to write frequency,
|
||||||
|
for example <code>1m</code> if your data is written every minute.
|
||||||
|
</info-popover>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,7 +7,10 @@
|
|||||||
"metrics": true,
|
"metrics": true,
|
||||||
"annotations": true,
|
"annotations": true,
|
||||||
"alerting": true,
|
"alerting": true,
|
||||||
"minInterval": true,
|
|
||||||
|
"queryOptions": {
|
||||||
|
"minInterval": true
|
||||||
|
},
|
||||||
|
|
||||||
"info": {
|
"info": {
|
||||||
"author": {
|
"author": {
|
||||||
|
22
public/app/plugins/datasource/influxdb/query_help.md
Normal file
22
public/app/plugins/datasource/influxdb/query_help.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#### Alias patterns
|
||||||
|
- replaced with measurement name
|
||||||
|
- $measurement = replaced with measurement name
|
||||||
|
- $1 - $9 = replaced with part of measurement name (if you separate your measurement name with dots)
|
||||||
|
- $col = replaced with column name
|
||||||
|
- $tag_exampletag = replaced with the value of the <i>exampletag</i> tag
|
||||||
|
- You can also use [[tag_exampletag]] pattern replacement syntax
|
||||||
|
|
||||||
|
#### Stacking and fill
|
||||||
|
- When stacking is enabled it is important that points align
|
||||||
|
- If there are missing points for one series it can cause gaps or missing bars
|
||||||
|
- You must use fill(0), and select a group by time low limit
|
||||||
|
- Use the group by time option below your queries and specify for example >10s if your metrics are written every 10 seconds
|
||||||
|
- This will insert zeros for series that are missing measurements and will make stacking work properly
|
||||||
|
|
||||||
|
#### Group by time
|
||||||
|
- Group by time is important, otherwise the query could return many thousands of datapoints that will slow down Grafana
|
||||||
|
- Leave the group by time field empty for each query and it will be calculated based on time range and pixel width of the graph
|
||||||
|
- If you use fill(0) or fill(null) set a low limit for the auto group by time interval
|
||||||
|
- The low limit can only be set in the group by time option below your queries
|
||||||
|
- You set a low limit by adding a greater sign before the interval
|
||||||
|
- Example: >60s if you write metrics to InfluxDB every 60 seconds
|
@ -143,7 +143,7 @@ define([
|
|||||||
expect(res.intervalMs).to.be(500);
|
expect(res.intervalMs).to.be(500);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('fixed user interval', function() {
|
it('fixed user min interval', function() {
|
||||||
var range = {from: dateMath.parse('now-10m'), to: dateMath.parse('now')};
|
var range = {from: dateMath.parse('now-10m'), to: dateMath.parse('now')};
|
||||||
var res = kbn.calculateInterval(range, 1600, '10s');
|
var res = kbn.calculateInterval(range, 1600, '10s');
|
||||||
expect(res.interval).to.be('10s');
|
expect(res.interval).to.be('10s');
|
||||||
|
Loading…
Reference in New Issue
Block a user