From 6ed1cbd5bb8bba9c80022710c9e71dd7c169db41 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Tue, 9 Oct 2018 12:11:18 +0900 Subject: [PATCH 1/4] set unit for CloudWatch GetMetricStatistics result --- pkg/tsdb/cloudwatch/cloudwatch.go | 7 +++++ pkg/tsdb/cloudwatch/constants.go | 30 +++++++++++++++++++ .../datasource/cloudwatch/datasource.ts | 2 +- .../cloudwatch/specs/datasource.test.ts | 2 ++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 pkg/tsdb/cloudwatch/constants.go diff --git a/pkg/tsdb/cloudwatch/cloudwatch.go b/pkg/tsdb/cloudwatch/cloudwatch.go index be14c6f96ec..fab8b92ef66 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch.go +++ b/pkg/tsdb/cloudwatch/cloudwatch.go @@ -362,6 +362,7 @@ func (e *CloudWatchExecutor) executeGetMetricDataQuery(ctx context.Context, regi } queryRes.Series = append(queryRes.Series, &series) + queryRes.Meta = simplejson.New() queryResponses = append(queryResponses, queryRes) } @@ -565,6 +566,12 @@ func parseResponse(resp *cloudwatch.GetMetricStatisticsOutput, query *CloudWatch } queryRes.Series = append(queryRes.Series, &series) + queryRes.Meta = simplejson.New() + if len(resp.Datapoints) > 0 && resp.Datapoints[0].Unit != nil { + if unit, ok := cloudwatchUnitMappings[*resp.Datapoints[0].Unit]; ok { + queryRes.Meta.Set("unit", unit) + } + } } return queryRes, nil diff --git a/pkg/tsdb/cloudwatch/constants.go b/pkg/tsdb/cloudwatch/constants.go new file mode 100644 index 00000000000..23817b1d133 --- /dev/null +++ b/pkg/tsdb/cloudwatch/constants.go @@ -0,0 +1,30 @@ +package cloudwatch + +var cloudwatchUnitMappings = map[string]string{ + "Seconds": "s", + "Microseconds": "µs", + "Milliseconds": "ms", + "Bytes": "bytes", + "Kilobytes": "kbytes", + "Megabytes": "mbytes", + "Gigabytes": "gbytes", + //"Terabytes": "", + "Bits": "bits", + //"Kilobits": "", + //"Megabits": "", + //"Gigabits": "", + //"Terabits": "", + "Percent": "percent", + //"Count": "", + "Bytes/Second": "Bps", + "Kilobytes/Second": "KBs", + "Megabytes/Second": "MBs", + "Gigabytes/Second": "GBs", + //"Terabytes/Second": "", + "Bits/Second": "bps", + "Kilobits/Second": "Kbits", + "Megabits/Second": "Mbits", + "Gigabits/Second": "Gbits", + //"Terabits/Second": "", + //"Count/Second": "", +} diff --git a/public/app/plugins/datasource/cloudwatch/datasource.ts b/public/app/plugins/datasource/cloudwatch/datasource.ts index e2b99d69df9..e096e44ac25 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.ts @@ -131,7 +131,7 @@ export default class CloudWatchDatasource { if (res.results) { _.forEach(res.results, queryRes => { _.forEach(queryRes.series, series => { - data.push({ target: series.name, datapoints: series.points }); + data.push({ target: series.name, datapoints: series.points, unit: queryRes.meta.unit || 'none' }); }); }); } diff --git a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts index 497c773687f..2825539f223 100644 --- a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts +++ b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts @@ -60,6 +60,7 @@ describe('CloudWatchDatasource', () => { A: { error: '', refId: 'A', + meta: {}, series: [ { name: 'CPUUtilization_Average', @@ -221,6 +222,7 @@ describe('CloudWatchDatasource', () => { A: { error: '', refId: 'A', + meta: {}, series: [ { name: 'TargetResponseTime_p90.00', From 37e749f6dab874ae891dc43fb0bf3b86c7a41d18 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Wed, 10 Oct 2018 13:56:58 +0900 Subject: [PATCH 2/4] fix crach bug --- pkg/tsdb/cloudwatch/cloudwatch.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/tsdb/cloudwatch/cloudwatch.go b/pkg/tsdb/cloudwatch/cloudwatch.go index fab8b92ef66..53ae2eae727 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch.go +++ b/pkg/tsdb/cloudwatch/cloudwatch.go @@ -129,10 +129,12 @@ func (e *CloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, queryCo if ae, ok := err.(awserr.Error); ok && ae.Code() == "500" { return err } - result.Results[queryRes.RefId] = queryRes if err != nil { - result.Results[queryRes.RefId].Error = err + result.Results[query.RefId] = &tsdb.QueryResult{ + Error: err, + } } + result.Results[queryRes.RefId] = queryRes return nil }) } @@ -269,7 +271,7 @@ func (e *CloudWatchExecutor) executeGetMetricDataQuery(ctx context.Context, regi for _, query := range queries { // 1 minutes resolution metrics is stored for 15 days, 15 * 24 * 60 = 21600 if query.HighResolution && (((endTime.Unix() - startTime.Unix()) / int64(query.Period)) > 21600) { - return nil, errors.New("too long query period") + return queryResponses, errors.New("too long query period") } mdq := &cloudwatch.MetricDataQuery{ From f0fb8123ae2ff377d861ffbe3b1ecfde07eba5e7 Mon Sep 17 00:00:00 2001 From: Mitsuhiro Tanda Date: Wed, 10 Oct 2018 14:07:08 +0900 Subject: [PATCH 3/4] add test for automatically unit set --- pkg/tsdb/cloudwatch/cloudwatch_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/tsdb/cloudwatch/cloudwatch_test.go b/pkg/tsdb/cloudwatch/cloudwatch_test.go index 719edba08ba..32b8c910f2b 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch_test.go +++ b/pkg/tsdb/cloudwatch/cloudwatch_test.go @@ -71,6 +71,7 @@ func TestCloudWatch(t *testing.T) { "p50.00": aws.Float64(30.0), "p90.00": aws.Float64(40.0), }, + Unit: aws.String("Seconds"), }, }, } @@ -103,6 +104,7 @@ func TestCloudWatch(t *testing.T) { So(queryRes.Series[1].Points[0][0].String(), ShouldEqual, null.FloatFrom(20.0).String()) So(queryRes.Series[2].Points[0][0].String(), ShouldEqual, null.FloatFrom(30.0).String()) So(queryRes.Series[3].Points[0][0].String(), ShouldEqual, null.FloatFrom(40.0).String()) + So(queryRes.Meta.Get("unit").MustString(), ShouldEqual, "s") }) Convey("terminate gap of data points", func() { @@ -118,6 +120,7 @@ func TestCloudWatch(t *testing.T) { "p50.00": aws.Float64(30.0), "p90.00": aws.Float64(40.0), }, + Unit: aws.String("Seconds"), }, { Timestamp: aws.Time(timestamp.Add(60 * time.Second)), @@ -127,6 +130,7 @@ func TestCloudWatch(t *testing.T) { "p50.00": aws.Float64(40.0), "p90.00": aws.Float64(50.0), }, + Unit: aws.String("Seconds"), }, { Timestamp: aws.Time(timestamp.Add(180 * time.Second)), @@ -136,6 +140,7 @@ func TestCloudWatch(t *testing.T) { "p50.00": aws.Float64(50.0), "p90.00": aws.Float64(60.0), }, + Unit: aws.String("Seconds"), }, }, } From 0612ce9b75c20ce385401a51b719d4561488dce9 Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Wed, 10 Oct 2018 09:38:42 +0200 Subject: [PATCH 4/4] cloudwatch: return early if execute query returns error This will stop a segfault from happening --- pkg/tsdb/cloudwatch/cloudwatch.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/tsdb/cloudwatch/cloudwatch.go b/pkg/tsdb/cloudwatch/cloudwatch.go index 53ae2eae727..61bbc04394a 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch.go +++ b/pkg/tsdb/cloudwatch/cloudwatch.go @@ -133,6 +133,7 @@ func (e *CloudWatchExecutor) executeTimeSeriesQuery(ctx context.Context, queryCo result.Results[query.RefId] = &tsdb.QueryResult{ Error: err, } + return nil } result.Results[queryRes.RefId] = queryRes return nil