Merge branch 'master' of github.com:grafana/grafana into develop

This commit is contained in:
Torkel Ödegaard 2017-11-21 16:05:18 +01:00
commit 9fc22e5a66
25 changed files with 1469 additions and 154 deletions

View File

@ -37,6 +37,7 @@
## Fixes ## Fixes
* **Gzip**: Fixes bug gravatar images when gzip was enabled [#5952](https://github.com/grafana/grafana/issues/5952) * **Gzip**: Fixes bug gravatar images when gzip was enabled [#5952](https://github.com/grafana/grafana/issues/5952)
* **Alert list**: Now shows alert state changes even after adding manual annotations on dashboard [#9951](https://github.com/grafana/grafana/issues/9951)
# 4.6.2 (2017-11-16) # 4.6.2 (2017-11-16)

View File

@ -0,0 +1,3 @@
FROM prom/prometheus:v2.0.0
ADD prometheus.yml /etc/prometheus/
ADD alert.rules /etc/prometheus/

View File

@ -0,0 +1,10 @@
# Alert Rules
ALERT AppCrash
IF process_open_fds > 0
FOR 15s
LABELS { severity="critical" }
ANNOTATIONS {
summary = "Number of open fds > 0",
description = "Just testing"
}

View File

@ -0,0 +1,35 @@
# my global config
global:
scrape_interval: 10s # By default, scrape targets every 15 seconds.
evaluation_interval: 10s # By default, scrape targets every 15 seconds.
# scrape_timeout is set to the global default (10s).
# Load and evaluate rules in this file every 'evaluation_interval' seconds.
#rule_files:
# - "alert.rules"
# - "first.rules"
# - "second.rules"
# alerting:
# alertmanagers:
# - scheme: http
# static_configs:
# - targets:
# - "127.0.0.1:9093"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node_exporter'
static_configs:
- targets: ['127.0.0.1:9100']
- job_name: 'fake-data-gen'
static_configs:
- targets: ['127.0.0.1:9091']
- job_name: 'grafana'
static_configs:
- targets: ['127.0.0.1:3000']

View File

@ -22,6 +22,7 @@ func GetAnnotations(c *middleware.Context) Response {
PanelId: c.QueryInt64("panelId"), PanelId: c.QueryInt64("panelId"),
Limit: c.QueryInt64("limit"), Limit: c.QueryInt64("limit"),
Tags: c.QueryStrings("tags"), Tags: c.QueryStrings("tags"),
Type: c.Query("type"),
} }
repo := annotations.GetRepository() repo := annotations.GetRepository()

View File

@ -194,7 +194,8 @@ func (hs *HttpServer) metricsEndpoint(ctx *macaron.Context) {
} }
func (hs *HttpServer) healthHandler(ctx *macaron.Context) { func (hs *HttpServer) healthHandler(ctx *macaron.Context) {
if ctx.Req.Method != "GET" || ctx.Req.URL.Path != "/api/health" { notHeadOrGet := ctx.Req.Method != http.MethodGet && ctx.Req.Method != http.MethodHead
if notHeadOrGet || ctx.Req.URL.Path != "/api/health" {
return return
} }

View File

@ -17,6 +17,7 @@ type ItemQuery struct {
DashboardId int64 `json:"dashboardId"` DashboardId int64 `json:"dashboardId"`
PanelId int64 `json:"panelId"` PanelId int64 `json:"panelId"`
Tags []string `json:"tags"` Tags []string `json:"tags"`
Type string `json:"type"`
Limit int64 `json:"limit"` Limit int64 `json:"limit"`
} }

View File

@ -158,6 +158,10 @@ func (r *SqlAnnotationRepo) Find(query *annotations.ItemQuery) ([]*annotations.I
params = append(params, query.From, query.To) params = append(params, query.From, query.To)
} }
if query.Type == "alert" {
sql.WriteString(` AND annotation.alert_id > 0`)
}
if len(query.Tags) > 0 { if len(query.Tags) > 0 {
keyValueFilters := []string{} keyValueFilters := []string{}

View File

@ -42,6 +42,7 @@ func TestAnnotations(t *testing.T) {
UserId: 1, UserId: 1,
DashboardId: 1, DashboardId: 1,
Text: "hello", Text: "hello",
Type: "alert",
Epoch: 10, Epoch: 10,
Tags: []string{"outage", "error", "type:outage", "server:server-1"}, Tags: []string{"outage", "error", "type:outage", "server:server-1"},
} }
@ -91,6 +92,19 @@ func TestAnnotations(t *testing.T) {
So(items, ShouldHaveLength, 0) So(items, ShouldHaveLength, 0)
}) })
Convey("Should not find one when type filter does not match", func() {
items, err := repo.Find(&annotations.ItemQuery{
OrgId: 1,
DashboardId: 1,
From: 1,
To: 15,
Type: "alert",
})
So(err, ShouldBeNil)
So(items, ShouldHaveLength, 0)
})
Convey("Should find one when all tag filters does match", func() { Convey("Should find one when all tag filters does match", func() {
items, err := repo.Find(&annotations.ItemQuery{ items, err := repo.Find(&annotations.ItemQuery{
OrgId: 1, OrgId: 1,

View File

@ -35,7 +35,7 @@ func NewMysqlQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndpoin
MacroEngine: NewMysqlMacroEngine(), MacroEngine: NewMysqlMacroEngine(),
} }
cnnstr := fmt.Sprintf("%s:%s@%s(%s)/%s?collation=utf8mb4_unicode_ci&parseTime=true&loc=UTC", cnnstr := fmt.Sprintf("%s:%s@%s(%s)/%s?collation=utf8mb4_unicode_ci&parseTime=true&loc=UTC&allowNativePasswords=true",
datasource.User, datasource.User,
datasource.Password, datasource.Password,
"tcp", "tcp",

View File

@ -48,7 +48,10 @@ function (_, $, coreModule) {
segment.html = selected.html || selected.value; segment.html = selected.html || selected.value;
segment.fake = false; segment.fake = false;
segment.expandable = selected.expandable; segment.expandable = selected.expandable;
segment.type = selected.type;
if (selected.type) {
segment.type = selected.type;
}
} }
else if (segment.custom !== 'false') { else if (segment.custom !== 'false') {
segment.value = value; segment.value = value;

View File

@ -11,7 +11,6 @@ import {metricsTabDirective} from './metrics_tab';
class MetricsPanelCtrl extends PanelCtrl { class MetricsPanelCtrl extends PanelCtrl {
scope: any; scope: any;
loading: boolean;
datasource: any; datasource: any;
datasourceName: any; datasourceName: any;
$q: any; $q: any;

View File

@ -31,6 +31,7 @@ export class PanelCtrl {
containerHeight: any; containerHeight: any;
events: Emitter; events: Emitter;
timing: any; timing: any;
loading: boolean;
constructor($scope, $injector) { constructor($scope, $injector) {
this.$injector = $injector; this.$injector = $injector;

View File

@ -1,2 +0,0 @@
declare var test: any;
export default test;

View File

@ -1,28 +1,27 @@
define([ import _ from 'lodash';
'lodash', import TableModel from 'app/core/table_model';
'app/core/table_model',
],
function (_, TableModel) {
'use strict';
function InfluxSeries(options) { export default class InfluxSeries {
series: any;
alias: any;
annotation: any;
constructor(options) {
this.series = options.series; this.series = options.series;
this.alias = options.alias; this.alias = options.alias;
this.annotation = options.annotation; this.annotation = options.annotation;
} }
var p = InfluxSeries.prototype; getTimeSeries() {
p.getTimeSeries = function() {
var output = []; var output = [];
var self = this;
var i, j; var i, j;
if (self.series.length === 0) { if (this.series.length === 0) {
return output; return output;
} }
_.each(self.series, function(series) { _.each(this.series, (series) => {
var columns = series.columns.length; var columns = series.columns.length;
var tags = _.map(series.tags, function(value, key) { var tags = _.map(series.tags, function(value, key) {
return key + ': ' + value; return key + ': ' + value;
@ -35,8 +34,8 @@ function (_, TableModel) {
seriesName = seriesName + '.' + columnName; seriesName = seriesName + '.' + columnName;
} }
if (self.alias) { if (this.alias) {
seriesName = self._getSeriesName(series, j); seriesName = this._getSeriesName(series, j);
} else if (series.tags) { } else if (series.tags) {
seriesName = seriesName + ' {' + tags.join(', ') + '}'; seriesName = seriesName + ' {' + tags.join(', ') + '}';
} }
@ -53,9 +52,9 @@ function (_, TableModel) {
}); });
return output; return output;
}; }
p._getSeriesName = function(series, index) { _getSeriesName(series, index) {
var regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g; var regex = /\$(\w+)|\[\[([\s\S]+?)\]\]/g;
var segments = series.name.split('.'); var segments = series.name.split('.');
@ -72,30 +71,29 @@ function (_, TableModel) {
if (!series.tags) { return match; } if (!series.tags) { return match; }
return series.tags[tag]; return series.tags[tag];
}); });
}; }
p.getAnnotations = function () { getAnnotations() {
var list = []; var list = [];
var self = this;
_.each(this.series, function (series) { _.each(this.series, (series) => {
var titleCol = null; var titleCol = null;
var timeCol = null; var timeCol = null;
var tagsCol = []; var tagsCol = [];
var textCol = null; var textCol = null;
_.each(series.columns, function(column, index) { _.each(series.columns, (column, index) => {
if (column === 'time') { timeCol = index; return; } if (column === 'time') { timeCol = index; return; }
if (column === 'sequence_number') { return; } if (column === 'sequence_number') { return; }
if (!titleCol) { titleCol = index; } if (!titleCol) { titleCol = index; }
if (column === self.annotation.titleColumn) { titleCol = index; return; } if (column === this.annotation.titleColumn) { titleCol = index; return; }
if (_.includes((self.annotation.tagsColumn || '').replace(' ', '').split(","), column)) { tagsCol.push(index); return; } if (_.includes((this.annotation.tagsColumn || '').replace(' ', '').split(","), column)) { tagsCol.push(index); return; }
if (column === self.annotation.textColumn) { textCol = index; return; } if (column === this.annotation.textColumn) { textCol = index; return; }
}); });
_.each(series.values, function (value) { _.each(series.values, (value) => {
var data = { var data = {
annotation: self.annotation, annotation: this.annotation,
time: + new Date(value[timeCol]), time: + new Date(value[timeCol]),
title: value[titleCol], title: value[titleCol],
// Remove empty values, then split in different tags for comma separated values // Remove empty values, then split in different tags for comma separated values
@ -108,18 +106,17 @@ function (_, TableModel) {
}); });
return list; return list;
}; }
p.getTable = function() { getTable() {
var table = new TableModel.default(); var table = new TableModel();
var self = this;
var i, j; var i, j;
if (self.series.length === 0) { if (this.series.length === 0) {
return table; return table;
} }
_.each(self.series, function(series, seriesIndex) { _.each(this.series, (series, seriesIndex) => {
if (seriesIndex === 0) { if (seriesIndex === 0) {
table.columns.push({text: 'Time', type: 'time'}); table.columns.push({text: 'Time', type: 'time'});
@ -151,7 +148,11 @@ function (_, TableModel) {
}); });
return table; return table;
}; }
}
return InfluxSeries;
});

View File

@ -1,5 +1,3 @@
///<reference path="../../../headers/common.d.ts" />
import _ from 'lodash'; import _ from 'lodash';
export default class ResponseParser { export default class ResponseParser {

View File

@ -1,5 +1,3 @@
import {describe, it, expect} from 'test/lib/common';
import InfluxQuery from '../influx_query'; import InfluxQuery from '../influx_query';
describe('InfluxQuery', function() { describe('InfluxQuery', function() {
@ -12,7 +10,7 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($__interval) fill(null)'); expect(queryText).toBe('SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($__interval) fill(null)');
}); });
}); });
@ -24,7 +22,7 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT mean("value") FROM "5m_avg"."cpu" WHERE $timeFilter GROUP BY time($__interval) fill(null)'); expect(queryText).toBe('SELECT mean("value") FROM "5m_avg"."cpu" WHERE $timeFilter GROUP BY time($__interval) fill(null)');
}); });
}); });
@ -43,7 +41,7 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT mean("value") /100 AS "text" FROM "cpu" WHERE $timeFilter GROUP BY time($__interval) fill(null)'); expect(queryText).toBe('SELECT mean("value") /100 AS "text" FROM "cpu" WHERE $timeFilter GROUP BY time($__interval) fill(null)');
}); });
}); });
@ -57,7 +55,7 @@ describe('InfluxQuery', function() {
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE ("hostname" = \'server\\\\1\') AND $timeFilter' expect(queryText).toBe('SELECT mean("value") FROM "cpu" WHERE ("hostname" = \'server\\\\1\') AND $timeFilter'
+ ' GROUP BY time($__interval)'); + ' GROUP BY time($__interval)');
}); });
@ -69,7 +67,7 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE ("app" =~ /e.*/) AND $timeFilter GROUP BY time($__interval)'); expect(queryText).toBe('SELECT mean("value") FROM "cpu" WHERE ("app" =~ /e.*/) AND $timeFilter GROUP BY time($__interval)');
}); });
}); });
@ -82,7 +80,7 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE ("hostname" = \'server1\' AND "app" = \'email\') AND ' + expect(queryText).toBe('SELECT mean("value") FROM "cpu" WHERE ("hostname" = \'server1\' AND "app" = \'email\') AND ' +
'$timeFilter GROUP BY time($__interval)'); '$timeFilter GROUP BY time($__interval)');
}); });
}); });
@ -96,7 +94,7 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE ("hostname" = \'server1\' OR "hostname" = \'server2\') AND ' + expect(queryText).toBe('SELECT mean("value") FROM "cpu" WHERE ("hostname" = \'server1\' OR "hostname" = \'server2\') AND ' +
'$timeFilter GROUP BY time($__interval)'); '$timeFilter GROUP BY time($__interval)');
}); });
}); });
@ -110,7 +108,7 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE ("value" > 5) AND $timeFilter'); expect(queryText).toBe('SELECT mean("value") FROM "cpu" WHERE ("value" > 5) AND $timeFilter');
}); });
}); });
@ -123,7 +121,7 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($__interval), "host"'); expect(queryText).toBe('SELECT mean("value") FROM "cpu" WHERE $timeFilter GROUP BY time($__interval), "host"');
}); });
}); });
@ -135,7 +133,7 @@ describe('InfluxQuery', function() {
groupBy: [], groupBy: [],
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT "value" FROM "cpu" WHERE $timeFilter'); expect(queryText).toBe('SELECT "value" FROM "cpu" WHERE $timeFilter');
}); });
}); });
@ -147,7 +145,7 @@ describe('InfluxQuery', function() {
groupBy: [{type: 'time'}, {type: 'fill', params: ['0']}], groupBy: [{type: 'time'}, {type: 'fill', params: ['0']}],
}, templateSrv, {}); }, templateSrv, {});
var queryText = query.render(); var queryText = query.render();
expect(queryText).to.be('SELECT "value" FROM "cpu" WHERE $timeFilter GROUP BY time($__interval) fill(0)'); expect(queryText).toBe('SELECT "value" FROM "cpu" WHERE $timeFilter GROUP BY time($__interval) fill(0)');
}); });
}); });
@ -160,10 +158,10 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
query.addGroupBy('tag(host)'); query.addGroupBy('tag(host)');
expect(query.target.groupBy.length).to.be(3); expect(query.target.groupBy.length).toBe(3);
expect(query.target.groupBy[1].type).to.be('tag'); expect(query.target.groupBy[1].type).toBe('tag');
expect(query.target.groupBy[1].params[0]).to.be('host'); expect(query.target.groupBy[1].params[0]).toBe('host');
expect(query.target.groupBy[2].type).to.be('fill'); expect(query.target.groupBy[2].type).toBe('fill');
}); });
it('should add tag last if no fill', function() { it('should add tag last if no fill', function() {
@ -173,8 +171,8 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
query.addGroupBy('tag(host)'); query.addGroupBy('tag(host)');
expect(query.target.groupBy.length).to.be(1); expect(query.target.groupBy.length).toBe(1);
expect(query.target.groupBy[0].type).to.be('tag'); expect(query.target.groupBy[0].type).toBe('tag');
}); });
}); });
@ -188,8 +186,8 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
query.addSelectPart(query.selectModels[0], 'mean'); query.addSelectPart(query.selectModels[0], 'mean');
expect(query.target.select[0].length).to.be(2); expect(query.target.select[0].length).toBe(2);
expect(query.target.select[0][1].type).to.be('mean'); expect(query.target.select[0][1].type).toBe('mean');
}); });
it('should replace sum by mean', function() { it('should replace sum by mean', function() {
@ -199,8 +197,8 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
query.addSelectPart(query.selectModels[0], 'sum'); query.addSelectPart(query.selectModels[0], 'sum');
expect(query.target.select[0].length).to.be(2); expect(query.target.select[0].length).toBe(2);
expect(query.target.select[0][1].type).to.be('sum'); expect(query.target.select[0][1].type).toBe('sum');
}); });
it('should add math before alias', function() { it('should add math before alias', function() {
@ -210,8 +208,8 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
query.addSelectPart(query.selectModels[0], 'math'); query.addSelectPart(query.selectModels[0], 'math');
expect(query.target.select[0].length).to.be(4); expect(query.target.select[0].length).toBe(4);
expect(query.target.select[0][2].type).to.be('math'); expect(query.target.select[0][2].type).toBe('math');
}); });
it('should add math last', function() { it('should add math last', function() {
@ -221,8 +219,8 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
query.addSelectPart(query.selectModels[0], 'math'); query.addSelectPart(query.selectModels[0], 'math');
expect(query.target.select[0].length).to.be(3); expect(query.target.select[0].length).toBe(3);
expect(query.target.select[0][2].type).to.be('math'); expect(query.target.select[0][2].type).toBe('math');
}); });
it('should replace math', function() { it('should replace math', function() {
@ -232,8 +230,8 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
query.addSelectPart(query.selectModels[0], 'math'); query.addSelectPart(query.selectModels[0], 'math');
expect(query.target.select[0].length).to.be(3); expect(query.target.select[0].length).toBe(3);
expect(query.target.select[0][2].type).to.be('math'); expect(query.target.select[0][2].type).toBe('math');
}); });
it('should add math when one only query part', function() { it('should add math when one only query part', function() {
@ -243,8 +241,8 @@ describe('InfluxQuery', function() {
}, templateSrv, {}); }, templateSrv, {});
query.addSelectPart(query.selectModels[0], 'math'); query.addSelectPart(query.selectModels[0], 'math');
expect(query.target.select[0].length).to.be(2); expect(query.target.select[0].length).toBe(2);
expect(query.target.select[0][1].type).to.be('math'); expect(query.target.select[0][1].type).toBe('math');
}); });
describe('when render adhoc filters', function() { describe('when render adhoc filters', function() {
@ -256,7 +254,7 @@ describe('InfluxQuery', function() {
{key: 'key2', operator: '!=', value: 'value2'}, {key: 'key2', operator: '!=', value: 'value2'},
]); ]);
expect(queryText).to.be('"key1" = \'value1\' AND "key2" != \'value2\''); expect(queryText).toBe('"key1" = \'value1\' AND "key2" != \'value2\'');
}); });
}); });

View File

@ -1,4 +1,3 @@
import {describe, it, expect} from 'test/lib/common';
import InfluxSeries from '../influx_series'; import InfluxSeries from '../influx_series';
describe('when generating timeseries from influxdb response', function() { describe('when generating timeseries from influxdb response', function() {
@ -19,24 +18,24 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var result = series.getTimeSeries(); var result = series.getTimeSeries();
expect(result.length).to.be(3); expect(result.length).toBe(3);
expect(result[0].target).to.be('cpu.mean {app: test, server: server1}'); expect(result[0].target).toBe('cpu.mean {app: test, server: server1}');
expect(result[0].datapoints[0][0]).to.be(10); expect(result[0].datapoints[0][0]).toBe(10);
expect(result[0].datapoints[0][1]).to.be(1431946625000); expect(result[0].datapoints[0][1]).toBe(1431946625000);
expect(result[0].datapoints[1][0]).to.be(20); expect(result[0].datapoints[1][0]).toBe(20);
expect(result[0].datapoints[1][1]).to.be(1431946626000); expect(result[0].datapoints[1][1]).toBe(1431946626000);
expect(result[1].target).to.be('cpu.max {app: test, server: server1}'); expect(result[1].target).toBe('cpu.max {app: test, server: server1}');
expect(result[1].datapoints[0][0]).to.be(11); expect(result[1].datapoints[0][0]).toBe(11);
expect(result[1].datapoints[0][1]).to.be(1431946625000); expect(result[1].datapoints[0][1]).toBe(1431946625000);
expect(result[1].datapoints[1][0]).to.be(21); expect(result[1].datapoints[1][0]).toBe(21);
expect(result[1].datapoints[1][1]).to.be(1431946626000); expect(result[1].datapoints[1][1]).toBe(1431946626000);
expect(result[2].target).to.be('cpu.min {app: test, server: server1}'); expect(result[2].target).toBe('cpu.min {app: test, server: server1}');
expect(result[2].datapoints[0][0]).to.be(9); expect(result[2].datapoints[0][0]).toBe(9);
expect(result[2].datapoints[0][1]).to.be(1431946625000); expect(result[2].datapoints[0][1]).toBe(1431946625000);
expect(result[2].datapoints[1][0]).to.be(19); expect(result[2].datapoints[1][0]).toBe(19);
expect(result[2].datapoints[1][1]).to.be(1431946626000); expect(result[2].datapoints[1][1]).toBe(1431946626000);
}); });
}); });
@ -47,9 +46,9 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var result = series.getTimeSeries(); var result = series.getTimeSeries();
expect(result[0].target).to.be('new series'); expect(result[0].target).toBe('new series');
expect(result[1].target).to.be('new series'); expect(result[1].target).toBe('new series');
expect(result[2].target).to.be('new series'); expect(result[2].target).toBe('new series');
}); });
}); });
@ -60,9 +59,9 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var result = series.getTimeSeries(); var result = series.getTimeSeries();
expect(result[0].target).to.be('alias: cpu -> server1 (cpu)'); expect(result[0].target).toBe('alias: cpu -> server1 (cpu)');
expect(result[1].target).to.be('alias: cpu -> server1 (cpu)'); expect(result[1].target).toBe('alias: cpu -> server1 (cpu)');
expect(result[2].target).to.be('alias: cpu -> server1 (cpu)'); expect(result[2].target).toBe('alias: cpu -> server1 (cpu)');
}); });
}); });
@ -90,8 +89,8 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var result = series.getTimeSeries(); var result = series.getTimeSeries();
expect(result[0].target).to.be('cpu {app: test, server: server1}'); expect(result[0].target).toBe('cpu {app: test, server: server1}');
expect(result[1].target).to.be('cpu {app: test2, server: server2}'); expect(result[1].target).toBe('cpu {app: test2, server: server2}');
}); });
}); });
@ -122,18 +121,18 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var result = series.getTimeSeries(); var result = series.getTimeSeries();
expect(result.length).to.be(2); expect(result.length).toBe(2);
expect(result[0].target).to.be('cpu.mean {app: test, server: server1}'); expect(result[0].target).toBe('cpu.mean {app: test, server: server1}');
expect(result[0].datapoints[0][0]).to.be(10); expect(result[0].datapoints[0][0]).toBe(10);
expect(result[0].datapoints[0][1]).to.be(1431946625000); expect(result[0].datapoints[0][1]).toBe(1431946625000);
expect(result[0].datapoints[1][0]).to.be(12); expect(result[0].datapoints[1][0]).toBe(12);
expect(result[0].datapoints[1][1]).to.be(1431946626000); expect(result[0].datapoints[1][1]).toBe(1431946626000);
expect(result[1].target).to.be('cpu.mean {app: test2, server: server2}'); expect(result[1].target).toBe('cpu.mean {app: test2, server: server2}');
expect(result[1].datapoints[0][0]).to.be(15); expect(result[1].datapoints[0][0]).toBe(15);
expect(result[1].datapoints[0][1]).to.be(1431946625000); expect(result[1].datapoints[0][1]).toBe(1431946625000);
expect(result[1].datapoints[1][0]).to.be(16); expect(result[1].datapoints[1][0]).toBe(16);
expect(result[1].datapoints[1][1]).to.be(1431946626000); expect(result[1].datapoints[1][1]).toBe(1431946626000);
}); });
}); });
@ -143,7 +142,7 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var result = series.getTimeSeries(); var result = series.getTimeSeries();
expect(result[0].target).to.be('new series'); expect(result[0].target).toBe('new series');
}); });
}); });
@ -154,8 +153,8 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var result = series.getTimeSeries(); var result = series.getTimeSeries();
expect(result[0].target).to.be('alias: cpu -> server1 (cpu)'); expect(result[0].target).toBe('alias: cpu -> server1 (cpu)');
expect(result[1].target).to.be('alias: cpu -> server2 (cpu)'); expect(result[1].target).toBe('alias: cpu -> server2 (cpu)');
}); });
}); });
@ -180,7 +179,7 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var result = series.getTimeSeries(); var result = series.getTimeSeries();
expect(result[0].target).to.be('alias: prod -> count'); expect(result[0].target).toBe('alias: prod -> count');
}); });
}); });
@ -201,9 +200,9 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var table = series.getTable(); var table = series.getTable();
expect(table.type).to.be('table'); expect(table.type).toBe('table');
expect(table.columns.length).to.be(5); expect(table.columns.length).toBe(5);
expect(table.rows[0]).to.eql([1431946625000, 'Africa', 'server2', 23, 10]); expect(table.rows[0]).toEqual([1431946625000, 'Africa', 'server2', 23, 10]);
}); });
}); });
@ -228,7 +227,7 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var annotations = series.getAnnotations(); var annotations = series.getAnnotations();
expect(annotations[0].tags.length).to.be(0); expect(annotations[0].tags.length).toBe(0);
}); });
}); });
@ -254,9 +253,9 @@ describe('when generating timeseries from influxdb response', function() {
var series = new InfluxSeries(options); var series = new InfluxSeries(options);
var annotations = series.getAnnotations(); var annotations = series.getAnnotations();
expect(annotations[0].tags.length).to.be(2); expect(annotations[0].tags.length).toBe(2);
expect(annotations[0].tags[0]).to.be('America'); expect(annotations[0].tags[0]).toBe('America');
expect(annotations[0].tags[1]).to.be('backend'); expect(annotations[0].tags[1]).toBe('backend');
}); });
}); });
}); });

View File

@ -1,6 +1,3 @@
import {describe, it, expect} from 'test/lib/common';
import queryPart from '../query_part'; import queryPart from '../query_part';
describe('InfluxQueryPart', () => { describe('InfluxQueryPart', () => {
@ -12,8 +9,8 @@ describe('InfluxQueryPart', () => {
params: ['10s'], params: ['10s'],
}); });
expect(part.text).to.be('derivative(10s)'); expect(part.text).toBe('derivative(10s)');
expect(part.render('mean(value)')).to.be('derivative(mean(value), 10s)'); expect(part.render('mean(value)')).toBe('derivative(mean(value), 10s)');
}); });
it('should nest spread function', () => { it('should nest spread function', () => {
@ -21,8 +18,8 @@ describe('InfluxQueryPart', () => {
type: 'spread' type: 'spread'
}); });
expect(part.text).to.be('spread()'); expect(part.text).toBe('spread()');
expect(part.render('value')).to.be('spread(value)'); expect(part.render('value')).toBe('spread(value)');
}); });
it('should handle suffix parts', () => { it('should handle suffix parts', () => {
@ -31,8 +28,8 @@ describe('InfluxQueryPart', () => {
params: ['/ 100'], params: ['/ 100'],
}); });
expect(part.text).to.be('math(/ 100)'); expect(part.text).toBe('math(/ 100)');
expect(part.render('mean(value)')).to.be('mean(value) / 100'); expect(part.render('mean(value)')).toBe('mean(value) / 100');
}); });
it('should handle alias parts', () => { it('should handle alias parts', () => {
@ -41,8 +38,8 @@ describe('InfluxQueryPart', () => {
params: ['test'], params: ['test'],
}); });
expect(part.text).to.be('alias(test)'); expect(part.text).toBe('alias(test)');
expect(part.render('mean(value)')).to.be('mean(value) AS "test"'); expect(part.render('mean(value)')).toBe('mean(value) AS "test"');
}); });
}); });

View File

@ -1,9 +1,10 @@
import _ from 'lodash'; import _ from 'lodash';
import {describe, it, expect} from 'test/lib/common';
import ResponseParser from '../response_parser'; import ResponseParser from '../response_parser';
describe("influxdb response parser", () => { describe('influxdb response parser', () => {
this.parser = new ResponseParser();
const parser = new ResponseParser();
describe("SHOW TAG response", () => { describe("SHOW TAG response", () => {
var query = 'SHOW TAG KEYS FROM "cpu"'; var query = 'SHOW TAG KEYS FROM "cpu"';
var response = { var response = {
@ -20,10 +21,10 @@ describe("influxdb response parser", () => {
] ]
}; };
var result = this.parser.parse(query, response); var result = parser.parse(query, response);
it("expects three results", () => { it("expects three results", () => {
expect(_.size(result)).to.be(3); expect(_.size(result)).toBe(3);
}); });
}); });
@ -45,12 +46,12 @@ describe("influxdb response parser", () => {
] ]
}; };
var result = this.parser.parse(query, response); var result = parser.parse(query, response);
it("should get two responses", () => { it("should get two responses", () => {
expect(_.size(result)).to.be(2); expect(_.size(result)).toBe(2);
expect(result[0].text).to.be("server1"); expect(result[0].text).toBe("server1");
expect(result[1].text).to.be("server2"); expect(result[1].text).toBe("server2");
}); });
}); });
@ -80,13 +81,13 @@ describe("influxdb response parser", () => {
] ]
}; };
var result = this.parser.parse(query, response); var result = parser.parse(query, response);
it("should get two responses", () => { it("should get two responses", () => {
expect(_.size(result)).to.be(3); expect(_.size(result)).toBe(3);
expect(result[0].text).to.be('site'); expect(result[0].text).toBe('site');
expect(result[1].text).to.be('api'); expect(result[1].text).toBe('api');
expect(result[2].text).to.be('webapi'); expect(result[2].text).toBe('webapi');
}); });
}); });
}); });
@ -110,9 +111,9 @@ describe("influxdb response parser", () => {
] ]
}; };
var result = this.parser.parse(query, response); var result = parser.parse(query, response);
it("should get two responses", () => { it("should get two responses", () => {
expect(_.size(result)).to.be(6); expect(_.size(result)).toBe(6);
}); });
}); });
@ -131,10 +132,10 @@ describe("influxdb response parser", () => {
] ]
}; };
var result = this.parser.parse(query, response); var result = parser.parse(query, response);
it("should get two responses", () => { it("should get two responses", () => {
expect(_.size(result)).to.be(1); expect(_.size(result)).toBe(1);
}); });
}); });
}); });

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@
"includes": [ "includes": [
{"type": "dashboard", "name": "Prometheus Stats", "path": "dashboards/prometheus_stats.json"}, {"type": "dashboard", "name": "Prometheus Stats", "path": "dashboards/prometheus_stats.json"},
{"type": "dashboard", "name": "Prometheus 2.0 Stats", "path": "dashboards/prometheus_2_stats.json"},
{"type": "dashboard", "name": "Grafana Stats", "path": "dashboards/grafana_stats.json"} {"type": "dashboard", "name": "Grafana Stats", "path": "dashboards/grafana_stats.json"}
], ],

View File

@ -688,7 +688,14 @@ function graphDirective($rootScope, timeSrv, popoverSrv, contextSrv) {
} }
elem.bind("plotselected", function (event, ranges) { elem.bind("plotselected", function (event, ranges) {
if (panel.xaxis.mode !== 'time') {
// Skip if panel in histogram or series mode
plot.clearSelection();
return;
}
if ((ranges.ctrlKey || ranges.metaKey) && contextSrv.isEditor) { if ((ranges.ctrlKey || ranges.metaKey) && contextSrv.isEditor) {
// Add annotation
setTimeout(() => { setTimeout(() => {
eventManager.updateTime(ranges.xaxis); eventManager.updateTime(ranges.xaxis);
}, 100); }, 100);
@ -703,6 +710,11 @@ function graphDirective($rootScope, timeSrv, popoverSrv, contextSrv) {
}); });
elem.bind("plotclick", function (event, pos, item) { elem.bind("plotclick", function (event, pos, item) {
if (panel.xaxis.mode !== 'time') {
// Skip if panel in histogram or series mode
return;
}
if ((pos.ctrlKey || pos.metaKey) && contextSrv.isEditor) { if ((pos.ctrlKey || pos.metaKey) && contextSrv.isEditor) {
// Skip if range selected (added in "plotselected" event handler) // Skip if range selected (added in "plotselected" event handler)
let isRangeSelection = pos.x !== pos.x1; let isRangeSelection = pos.x !== pos.x1;

View File

@ -104,7 +104,7 @@ describe('SingleStatCtrl', function() {
}); });
it('should set formatted value', function() { it('should set formatted value', function() {
expect(ctx.data.valueFormatted).to.be(moment(1505634997920).format('MM/DD/YYYY H:mm:ss a')); expect(ctx.data.valueFormatted).to.be(moment(1505634997920).format('MM/DD/YYYY h:mm:ss a'));
}); });
}); });

View File

@ -280,7 +280,7 @@
.graph-annotation__header { .graph-annotation__header {
background-color: $popover-border-color; background-color: $popover-border-color;
padding: 0.40rem 0.65rem; padding: 6px 10px;
display: flex; display: flex;
} }