Commit 07e192ff by Torkel Ödegaard

change: more work on changing default group by time interval to min interval setting

parent e8e1f1bc
......@@ -11,12 +11,10 @@ type DataSourcePlugin struct {
Annotations bool `json:"annotations"`
Metrics bool `json:"metrics"`
Alerting bool `json:"alerting"`
MinInterval bool `json:"minInterval,omitempty"`
CacheTimeout bool `json:"cacheTimeout,omitempty"`
MaxDataPoints bool `json:"maxDataPoints,omitempty"`
QueryOptions map[string]bool `json:"queryOptions,omitempty"`
BuiltIn bool `json:"builtIn,omitempty"`
Mixed bool `json:"mixed,omitempty"`
HasHelp bool `json:"hasHelp,omitempty"`
HasQueryHelp bool `json:"hasQueryHelp,omitempty"`
Routes []*AppPluginRoute `json:"-"`
}
......@@ -31,12 +29,12 @@ func (p *DataSourcePlugin) Load(decoder *json.Decoder, pluginDir string) error {
}
// 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) {
helpPath = filepath.Join(p.PluginDir, "help.md")
helpPath = filepath.Join(p.PluginDir, "query_help.md")
}
if _, err := os.Stat(helpPath); err == nil {
p.HasHelp = true
p.HasQueryHelp = true
}
DataSources[p.Id] = p
......
......@@ -163,21 +163,15 @@ function($, _) {
ms: 0.001
};
kbn.calculateInterval = function(range, resolution, userInterval) {
kbn.calculateInterval = function(range, resolution, lowLimitInterval) {
var lowLimitMs = 1; // 1 millisecond default low limit
var intervalMs, lowLimitInterval;
var intervalMs;
if (userInterval) {
if (userInterval[0] === '>') {
lowLimitInterval = userInterval.slice(1);
lowLimitMs = kbn.interval_to_ms(lowLimitInterval);
}
else {
return {
intervalMs: kbn.interval_to_ms(userInterval),
interval: userInterval,
};
if (lowLimitInterval) {
if (lowLimitInterval[0] === '>') {
lowLimitInterval = lowLimitInterval.slice(1);
}
lowLimitMs = kbn.interval_to_ms(lowLimitInterval);
}
intervalMs = kbn.round_interval((range.to.valueOf() - range.from.valueOf()) / resolution);
......
......@@ -16,12 +16,10 @@ export class MetricsTabCtrl {
addQueryDropdown: any;
queryTroubleshooterOpen: boolean;
helpOpen: boolean;
hasHelp: boolean;
helpHtml: string;
hasMinInterval: boolean;
hasCacheTimeout: boolean;
hasMaxDataPoints: boolean;
optionsOpen: boolean;
hasQueryHelp: boolean;
helpHtml: string;
queryOptions: any;
/** @ngInject */
constructor($scope, private $sce, private datasourceSrv, private backendSrv, private $timeout) {
......@@ -46,10 +44,8 @@ export class MetricsTabCtrl {
}
updateDatasourceOptions() {
this.hasHelp = this.current.meta.hasHelp;
this.hasMinInterval = this.current.meta.minInterval === true;
this.hasCacheTimeout = this.current.meta.cacheTimeout === true;
this.hasMaxDataPoints = this.current.meta.maxDataPoints === true;
this.hasQueryHelp = this.current.meta.hasQueryHelp;
this.queryOptions = this.current.meta.queryOptions;
}
getOptions(includeBuiltin) {
......@@ -89,7 +85,7 @@ export class MetricsTabCtrl {
this.queryTroubleshooterOpen = false;
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();
this.helpHtml = this.$sce.trustAsHtml(md.render(res));
});
......
......@@ -15,12 +15,12 @@
<div class="gf-form gf-form--grow">
<label class="gf-form-label gf-form-label--grow"></label>
</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()">
<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>
</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()">
<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>
......@@ -33,8 +33,8 @@
</div>
<div>
<div class="" ng-if="ctrl.optionsOpen">
<div class="gf-form gf-form--flex-end" ng-if="ctrl.hasMinInterval">
<div ng-if="ctrl.optionsOpen">
<div class="gf-form gf-form--flex-end" ng-if="ctrl.queryOptions.minInterval">
<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()" />
<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.
</info-popover>
</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>
<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">
......@@ -51,7 +51,7 @@
cache timeout. Specify a numeric value in seconds.
</info-popover>
</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>
<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">
......
......@@ -54,7 +54,7 @@ export class IntervalVariable implements Variable {
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);
}
......
......@@ -25,13 +25,14 @@
<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>
</div>
</div>
<h3 class="page-heading">Default query settings</h3>
<div class="gf-form-group">
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label">Group by time interval</span>
<input class="gf-form-input max-width-9" type="text" ng-model="ctrl.current.jsonData.timeInterval" spellcheck='false' placeholder="example: >10s">
<span class="gf-form-label width-9">Min interval</span>
<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>
......@@ -10,8 +10,11 @@
"metrics": true,
"alerting": true,
"annotations": true,
"queryOptions": {
"maxDataPoints": true,
"cacheTimeout": true,
"cacheTimeout": true
},
"info": {
"author": {
......
......@@ -24,10 +24,14 @@
</div>
<div class="gf-form-group">
<div class="gf-form max-width-21">
<span class="gf-form-label">Default group by time</span>
<input type="text" class="gf-form-input width-6" ng-model="ctrl.current.jsonData.timeInterval"
spellcheck='false' placeholder="example: >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>
<div class="gf-form-inline">
<div class="gf-form">
<span class="gf-form-label">Min interval</span>
<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>
......@@ -7,7 +7,10 @@
"metrics": true,
"annotations": true,
"alerting": true,
"minInterval": true,
"queryOptions": {
"minInterval": true
},
"info": {
"author": {
......
#### 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 &gt;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: &gt;60s if you write metrics to InfluxDB every 60 seconds
......@@ -143,8 +143,8 @@ define([
expect(res.intervalMs).to.be(500);
});
it('fixed user interval', function() {
var range = { from: dateMath.parse('now-10m'), to: dateMath.parse('now') };
it('fixed user min interval', function() {
var range = {from: dateMath.parse('now-10m'), to: dateMath.parse('now')};
var res = kbn.calculateInterval(range, 1600, '10s');
expect(res.interval).to.be('10s');
expect(res.intervalMs).to.be(10000);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment