mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudWatch: Remove HighResolution toggle since it's not being used (#20440)
* Remove highres flag since it's not being used * Remove not used code. Init id field correctly * Fix broken tests * Remove GMS related calculations * Rename period field * Add breaking changes to changelog. Also update upgrading docs * Update snapshot * Update docs after feedback * Changes after feedback
This commit is contained in:
parent
d1c523838b
commit
ec18e2bfc3
@ -68,6 +68,10 @@
|
||||
## Breaking changes
|
||||
* **CloudWatch**: Pre Grafana 6.5.0, the CloudWatch datasource used the GetMetricStatistics API for all queries that did not have an ´id´ and did not have an ´expression´ defined in the query editor. The GetMetricStatistics API has a limit of 400 transactions per second. In this release, all queries use the GetMetricData API. The GetMetricData API has a limit of 50 transactions per second and 100 metrics per transaction. Also the GetMetricData API pricing is different from GetMetricStatistics. While GetMetricStatistics qualified for the CloudWatch API free tier, this is not the case for GetMetricData calls. For more information, please refer to the CloudWatch pricing page (https://aws.amazon.com/cloudwatch/pricing/). Read more about GetMetricData limits in [upgrading to 6.5](https://grafana.com/docs/installation/upgrading/#upgrading-to-v6-5).
|
||||
|
||||
* **CloudWatch**: The GetMetricData API does not return metric unit, so unit auto detection in panels is no longer supported.
|
||||
|
||||
* **CloudWatch**: The `HighRes` switch has been removed from the query editor. Read more about this in [upgrading to 6.5](https://grafana.com/docs/installation/upgrading/#upgrading-to-v6-5).
|
||||
|
||||
* **CloudWatch**: In previous versions of Grafana, there was partial support for using multi template variables as dimension values. When a multi template variable is being used for dimension values in Grafana 6.5, a [search expression](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-search-expressions.html) will be generated. In the GetMetricData API, expressions are limited to 1024 characters, so it might be the case that this limit is reached when a multi template variable that has a lot of values is being used. Read about the suggested workaround in [upgrading to 6.5](https://grafana.com/docs/installation/upgrading/#upgrading-to-v6-5).
|
||||
|
||||
# 6.4.4 (2019-11-06)
|
||||
|
@ -206,4 +206,6 @@ Plugins that need updating:
|
||||
|
||||
Pre Grafana 6.5.0, the CloudWatch datasource used the GetMetricStatistics API for all queries that did not have an ´id´ and did not have an ´expression´ defined in the query editor. The GetMetricStatistics API has a limit of 400 transactions per second (TPS). In this release, all queries use the GetMetricData API which has a limit of 50 TPS and 100 metrics per transaction. We expect this transition to be smooth for most of our users, but in case you do face throttling issues we suggest you increase the TPS quota. To do that, please visit the [AWS Service Quotas console](https://console.aws.amazon.com/servicequotas/home?r#!/services/monitoring/quotas/L-5E141212). For more details around CloudWatch API limits, [see CloudWatch docs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch_limits.html).
|
||||
|
||||
Each request to the GetMetricData API can include 100 queries. This means that each panel in Grafana will only issue one GetMetricData request, regardless of the number of query rows that are present in the panel. Consequently as it is no longer possible to set `HighRes` on a per query level anymore, this switch is now removed from the query editor. High resolution can still be achieved by choosing a smaller minimum period in the query editor.
|
||||
|
||||
The handling of multi template variables in dimension values has been changed in Grafana 6.5. When a multi template variable is being used, Grafana will generate a search expression. In the GetMetricData API, expressions are limited to 1024 characters, so it might be the case that this limit is reached when a multi template variable that has a lot of values is being used. If this is the case, we suggest you start using `*` wildcard as dimension value instead of a multi template variable.
|
||||
|
@ -16,8 +16,6 @@ type cloudWatchQuery struct {
|
||||
Dimensions map[string][]string
|
||||
Period int
|
||||
Alias string
|
||||
Identifier string
|
||||
HighResolution bool
|
||||
MatchExact bool
|
||||
UsedExpression string
|
||||
RequestExceededMaxLimit bool
|
||||
|
@ -16,7 +16,6 @@ func TestCloudWatchQuery(t *testing.T) {
|
||||
Stats: "Average",
|
||||
Period: 300,
|
||||
Id: "id1",
|
||||
Identifier: "id1",
|
||||
}
|
||||
|
||||
Convey("it is a search expression", func() {
|
||||
@ -36,7 +35,6 @@ func TestCloudWatchQuery(t *testing.T) {
|
||||
Stats: "Average",
|
||||
Period: 300,
|
||||
Id: "id1",
|
||||
Identifier: "id1",
|
||||
MatchExact: true,
|
||||
Dimensions: map[string][]string{
|
||||
"InstanceId": {"i-12345678"},
|
||||
@ -60,7 +58,6 @@ func TestCloudWatchQuery(t *testing.T) {
|
||||
Stats: "Average",
|
||||
Period: 300,
|
||||
Id: "id1",
|
||||
Identifier: "id1",
|
||||
Dimensions: map[string][]string{
|
||||
"InstanceId": {"i-12345678", "i-34562312"},
|
||||
},
|
||||
@ -83,7 +80,6 @@ func TestCloudWatchQuery(t *testing.T) {
|
||||
Stats: "Average",
|
||||
Period: 300,
|
||||
Id: "id1",
|
||||
Identifier: "id1",
|
||||
Dimensions: map[string][]string{
|
||||
"InstanceId": {"i-12345678", "*"},
|
||||
"InstanceType": {"abc", "def"},
|
||||
@ -108,7 +104,6 @@ func TestCloudWatchQuery(t *testing.T) {
|
||||
Period: 300,
|
||||
Id: "id1",
|
||||
MatchExact: false,
|
||||
Identifier: "id1",
|
||||
Dimensions: make(map[string][]string),
|
||||
}
|
||||
Convey("and match exact is false", func() {
|
||||
@ -152,7 +147,6 @@ func TestCloudWatchQuery(t *testing.T) {
|
||||
Stats: "Average",
|
||||
Period: 300,
|
||||
Id: "id1",
|
||||
Identifier: "id1",
|
||||
MatchExact: false,
|
||||
Dimensions: map[string][]string{
|
||||
"InstanceId": {"i-12345678"},
|
||||
|
@ -1,7 +1,6 @@
|
||||
package cloudwatch
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
@ -30,11 +29,6 @@ func (e *CloudWatchExecutor) buildMetricDataInput(queryContext *tsdb.TsdbQuery,
|
||||
ScanBy: aws.String("TimestampAscending"),
|
||||
}
|
||||
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, &queryError{errors.New("too long query period"), query.RefId}
|
||||
}
|
||||
|
||||
metricDataQuery, err := e.buildMetricDataQuery(query)
|
||||
if err != nil {
|
||||
return nil, &queryError{err, query.RefId}
|
||||
|
@ -19,7 +19,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"LoadBalancer": {"lb1", "lb2", "lb3"},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: matchExact,
|
||||
}
|
||||
@ -38,7 +37,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"InstanceId": {"i-123", "i-456", "i-789"},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: matchExact,
|
||||
}
|
||||
@ -55,7 +53,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"LoadBalancer": {"*"},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: matchExact,
|
||||
}
|
||||
@ -72,7 +69,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"LoadBalancer": {"*"},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: matchExact,
|
||||
}
|
||||
@ -90,7 +86,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"InstanceId": {"i-123", "*", "i-789"},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: matchExact,
|
||||
}
|
||||
@ -110,7 +105,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"LoadBalancer": {"lb1", "lb2", "lb3"},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: matchExact,
|
||||
}
|
||||
@ -128,7 +122,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"InstanceId": {"i-123", "i-456", "i-789"},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: matchExact,
|
||||
}
|
||||
@ -145,7 +138,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"LoadBalancer": {"*"},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: matchExact,
|
||||
}
|
||||
@ -163,7 +155,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"InstanceId": {"i-123", "*", "i-789"},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: matchExact,
|
||||
}
|
||||
@ -188,7 +179,6 @@ func TestMetricDataQueryBuilder(t *testing.T) {
|
||||
"lb6": {`l\\(b5"`},
|
||||
},
|
||||
Period: 300,
|
||||
Identifier: "id1",
|
||||
Expression: "",
|
||||
MatchExact: true,
|
||||
}
|
||||
|
@ -26,19 +26,18 @@ func (e *CloudWatchExecutor) transformRequestQueriesToCloudWatchQueries(requestQ
|
||||
}
|
||||
|
||||
query := &cloudWatchQuery{
|
||||
Id: id,
|
||||
RefId: requestQuery.RefId,
|
||||
Region: requestQuery.Region,
|
||||
Namespace: requestQuery.Namespace,
|
||||
MetricName: requestQuery.MetricName,
|
||||
Dimensions: requestQuery.Dimensions,
|
||||
Stats: *stat,
|
||||
Period: requestQuery.Period,
|
||||
Alias: requestQuery.Alias,
|
||||
Expression: requestQuery.Expression,
|
||||
ReturnData: requestQuery.ReturnData,
|
||||
HighResolution: requestQuery.HighResolution,
|
||||
MatchExact: requestQuery.MatchExact,
|
||||
Id: id,
|
||||
RefId: requestQuery.RefId,
|
||||
Region: requestQuery.Region,
|
||||
Namespace: requestQuery.Namespace,
|
||||
MetricName: requestQuery.MetricName,
|
||||
Dimensions: requestQuery.Dimensions,
|
||||
Stats: *stat,
|
||||
Period: requestQuery.Period,
|
||||
Alias: requestQuery.Alias,
|
||||
Expression: requestQuery.Expression,
|
||||
ReturnData: requestQuery.ReturnData,
|
||||
MatchExact: requestQuery.MatchExact,
|
||||
}
|
||||
|
||||
if _, ok := cloudwatchQueries[id]; ok {
|
||||
|
@ -15,14 +15,13 @@ func TestQueryTransformer(t *testing.T) {
|
||||
Convey("one cloudwatchQuery is generated when its request query has one stat", func() {
|
||||
requestQueries := []*requestQuery{
|
||||
{
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
HighResolution: false,
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
},
|
||||
}
|
||||
|
||||
@ -34,14 +33,13 @@ func TestQueryTransformer(t *testing.T) {
|
||||
Convey("two cloudwatchQuery is generated when there's two stats", func() {
|
||||
requestQueries := []*requestQuery{
|
||||
{
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "Sum"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
HighResolution: false,
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "Sum"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
},
|
||||
}
|
||||
|
||||
@ -53,14 +51,13 @@ func TestQueryTransformer(t *testing.T) {
|
||||
Convey("that id will be used in the cloudwatch query", func() {
|
||||
requestQueries := []*requestQuery{
|
||||
{
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average"}),
|
||||
Period: 600,
|
||||
Id: "myid",
|
||||
HighResolution: false,
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average"}),
|
||||
Period: 600,
|
||||
Id: "myid",
|
||||
},
|
||||
}
|
||||
|
||||
@ -75,14 +72,13 @@ func TestQueryTransformer(t *testing.T) {
|
||||
Convey("id will be generated based on ref id if query only has one stat", func() {
|
||||
requestQueries := []*requestQuery{
|
||||
{
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
HighResolution: false,
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
},
|
||||
}
|
||||
|
||||
@ -95,14 +91,13 @@ func TestQueryTransformer(t *testing.T) {
|
||||
Convey("id will be generated based on ref and stat name if query has two stats", func() {
|
||||
requestQueries := []*requestQuery{
|
||||
{
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "Sum"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
HighResolution: false,
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "Sum"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
},
|
||||
}
|
||||
|
||||
@ -117,14 +112,13 @@ func TestQueryTransformer(t *testing.T) {
|
||||
Convey("dot should be removed when query has more than one stat and one of them is a percentile", func() {
|
||||
requestQueries := []*requestQuery{
|
||||
{
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "p46.32"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
HighResolution: false,
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "p46.32"}),
|
||||
Period: 600,
|
||||
Id: "",
|
||||
},
|
||||
}
|
||||
|
||||
@ -137,24 +131,22 @@ func TestQueryTransformer(t *testing.T) {
|
||||
Convey("should return an error if two queries have the same id", func() {
|
||||
requestQueries := []*requestQuery{
|
||||
{
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "p46.32"}),
|
||||
Period: 600,
|
||||
Id: "myId",
|
||||
HighResolution: false,
|
||||
RefId: "D",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "p46.32"}),
|
||||
Period: 600,
|
||||
Id: "myId",
|
||||
},
|
||||
{
|
||||
RefId: "E",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "p46.32"}),
|
||||
Period: 600,
|
||||
Id: "myId",
|
||||
HighResolution: false,
|
||||
RefId: "E",
|
||||
Region: "us-east-1",
|
||||
Namespace: "ec2",
|
||||
MetricName: "CPUUtilization",
|
||||
Statistics: aws.StringSlice([]string{"Average", "p46.32"}),
|
||||
Period: 600,
|
||||
Id: "myId",
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -97,23 +97,21 @@ func parseRequestQuery(model *simplejson.Json, refId string) (*requestQuery, err
|
||||
returnData = true
|
||||
}
|
||||
|
||||
highResolution := model.Get("highResolution").MustBool(false)
|
||||
matchExact := model.Get("matchExact").MustBool(true)
|
||||
|
||||
return &requestQuery{
|
||||
RefId: refId,
|
||||
Region: region,
|
||||
Namespace: namespace,
|
||||
MetricName: metricName,
|
||||
Dimensions: dimensions,
|
||||
Statistics: aws.StringSlice(statistics),
|
||||
Period: period,
|
||||
Alias: alias,
|
||||
Id: id,
|
||||
Expression: expression,
|
||||
ReturnData: returnData,
|
||||
HighResolution: highResolution,
|
||||
MatchExact: matchExact,
|
||||
RefId: refId,
|
||||
Region: region,
|
||||
Namespace: namespace,
|
||||
MetricName: metricName,
|
||||
Dimensions: dimensions,
|
||||
Statistics: aws.StringSlice(statistics),
|
||||
Period: period,
|
||||
Alias: alias,
|
||||
Id: id,
|
||||
Expression: expression,
|
||||
ReturnData: returnData,
|
||||
MatchExact: matchExact,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -22,10 +22,9 @@ func TestRequestParser(t *testing.T) {
|
||||
"InstanceId": []interface{}{"test"},
|
||||
"InstanceType": []interface{}{"test2", "test3"},
|
||||
},
|
||||
"statistics": []interface{}{"Average"},
|
||||
"period": "600",
|
||||
"hide": false,
|
||||
"highResolution": false,
|
||||
"statistics": []interface{}{"Average"},
|
||||
"period": "600",
|
||||
"hide": false,
|
||||
})
|
||||
|
||||
res, err := parseRequestQuery(query, "ref1")
|
||||
@ -38,7 +37,6 @@ func TestRequestParser(t *testing.T) {
|
||||
So(res.Expression, ShouldEqual, "")
|
||||
So(res.Period, ShouldEqual, 600)
|
||||
So(res.ReturnData, ShouldEqual, true)
|
||||
So(res.HighResolution, ShouldEqual, false)
|
||||
So(len(res.Dimensions), ShouldEqual, 2)
|
||||
So(len(res.Dimensions["InstanceId"]), ShouldEqual, 1)
|
||||
So(len(res.Dimensions["InstanceType"]), ShouldEqual, 2)
|
||||
@ -59,10 +57,9 @@ func TestRequestParser(t *testing.T) {
|
||||
"InstanceId": "test",
|
||||
"InstanceType": "test2",
|
||||
},
|
||||
"statistics": []interface{}{"Average"},
|
||||
"period": "600",
|
||||
"hide": false,
|
||||
"highResolution": false,
|
||||
"statistics": []interface{}{"Average"},
|
||||
"period": "600",
|
||||
"hide": false,
|
||||
})
|
||||
|
||||
res, err := parseRequestQuery(query, "ref1")
|
||||
@ -75,7 +72,6 @@ func TestRequestParser(t *testing.T) {
|
||||
So(res.Expression, ShouldEqual, "")
|
||||
So(res.Period, ShouldEqual, 600)
|
||||
So(res.ReturnData, ShouldEqual, true)
|
||||
So(res.HighResolution, ShouldEqual, false)
|
||||
So(len(res.Dimensions), ShouldEqual, 2)
|
||||
So(len(res.Dimensions["InstanceId"]), ShouldEqual, 1)
|
||||
So(len(res.Dimensions["InstanceType"]), ShouldEqual, 1)
|
||||
|
@ -63,7 +63,7 @@ func parseGetMetricDataTimeSeries(metricDataResults map[string]*cloudwatch.Metri
|
||||
result := tsdb.TimeSeriesSlice{}
|
||||
for label, metricDataResult := range metricDataResults {
|
||||
if *metricDataResult.StatusCode != "Complete" {
|
||||
return nil, fmt.Errorf("too many datapoint requested in query %s. Please try to reduce the time range", query.RefId)
|
||||
return nil, fmt.Errorf("too many datapoints requested in query %s. Please try to reduce the time range", query.RefId)
|
||||
}
|
||||
|
||||
for _, message := range metricDataResult.Messages {
|
||||
|
@ -27,7 +27,6 @@ type requestQuery struct {
|
||||
ExtendedStatistics []*string
|
||||
Period int
|
||||
Alias string
|
||||
HighResolution bool
|
||||
MatchExact bool
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,6 @@ const setup = () => {
|
||||
period: '',
|
||||
expression: '',
|
||||
alias: '',
|
||||
highResolution: false,
|
||||
matchExact: true,
|
||||
},
|
||||
datasource,
|
||||
|
@ -51,12 +51,16 @@ export class QueryEditor extends PureComponent<Props, State> {
|
||||
query.region = 'default';
|
||||
}
|
||||
|
||||
if (!query.statistics || !query.statistics.length) {
|
||||
query.statistics = ['Average'];
|
||||
if (!query.id) {
|
||||
query.id = '';
|
||||
}
|
||||
|
||||
if (!query.hasOwnProperty('highResolution')) {
|
||||
query.highResolution = false;
|
||||
if (!query.alias) {
|
||||
query.alias = '';
|
||||
}
|
||||
|
||||
if (!query.statistics || !query.statistics.length) {
|
||||
query.statistics = ['Average'];
|
||||
}
|
||||
|
||||
if (!query.hasOwnProperty('matchExact')) {
|
||||
@ -198,11 +202,7 @@ export class QueryEditor extends PureComponent<Props, State> {
|
||||
)}
|
||||
<div className="gf-form-inline">
|
||||
<div className="gf-form">
|
||||
<QueryField
|
||||
className="query-keyword"
|
||||
label="Min Period"
|
||||
tooltip="Minimum interval between points in seconds"
|
||||
>
|
||||
<QueryField className="query-keyword" label="Period" tooltip="Minimum interval between points in seconds">
|
||||
<Input
|
||||
className="gf-form-input width-8"
|
||||
value={query.period || ''}
|
||||
@ -220,12 +220,6 @@ export class QueryEditor extends PureComponent<Props, State> {
|
||||
>
|
||||
<Alias value={query.alias} onChange={(value: string) => this.onChange({ ...query, alias: value })} />
|
||||
</QueryField>
|
||||
<Switch
|
||||
label="HighRes"
|
||||
labelClass="query-keyword"
|
||||
checked={query.highResolution}
|
||||
onChange={() => this.onChange({ ...query, highResolution: !query.highResolution })}
|
||||
/>
|
||||
<Switch
|
||||
label="Match Exact"
|
||||
labelClass="query-keyword"
|
||||
|
@ -248,7 +248,7 @@ Array [
|
||||
<label
|
||||
className="gf-form-label width-8 query-keyword"
|
||||
>
|
||||
Min Period
|
||||
Period
|
||||
<div
|
||||
className="gf-form-help-icon gf-form-help-icon--right-normal"
|
||||
onMouseEnter={[Function]}
|
||||
@ -312,33 +312,6 @@ Array [
|
||||
<label
|
||||
className="gf-form gf-form-switch-container "
|
||||
htmlFor="1"
|
||||
>
|
||||
<div
|
||||
className="gf-form-label query-keyword pointer"
|
||||
>
|
||||
HighRes
|
||||
</div>
|
||||
<div
|
||||
className="gf-form-switch "
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
id="1"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
className="gf-form-switch__slider"
|
||||
/>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="gf-form-switch-container-react"
|
||||
>
|
||||
<label
|
||||
className="gf-form gf-form-switch-container "
|
||||
htmlFor="2"
|
||||
>
|
||||
<div
|
||||
className="gf-form-label query-keyword pointer"
|
||||
@ -359,7 +332,7 @@ Array [
|
||||
>
|
||||
<input
|
||||
checked={true}
|
||||
id="2"
|
||||
id="1"
|
||||
onChange={[Function]}
|
||||
type="checkbox"
|
||||
/>
|
||||
|
@ -95,7 +95,6 @@
|
||||
"VolumeId": "$volume"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "VolumeReadBytes",
|
||||
"namespace": "AWS/EBS",
|
||||
@ -191,7 +190,6 @@
|
||||
"VolumeId": "$volume"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "VolumeWriteBytes",
|
||||
"namespace": "AWS/EBS",
|
||||
@ -287,7 +285,6 @@
|
||||
"VolumeId": "$volume"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "VolumeTotalReadTime",
|
||||
"namespace": "AWS/EBS",
|
||||
@ -383,7 +380,6 @@
|
||||
"VolumeId": "$volume"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "VolumeTotalWriteTime",
|
||||
"namespace": "AWS/EBS",
|
||||
@ -479,7 +475,6 @@
|
||||
"VolumeId": "$volume"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "VolumeReadOps",
|
||||
"namespace": "AWS/EBS",
|
||||
@ -575,7 +570,6 @@
|
||||
"VolumeId": "$volume"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "VolumeWriteOps",
|
||||
"namespace": "AWS/EBS",
|
||||
@ -671,7 +665,6 @@
|
||||
"VolumeId": "$volume"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "VolumeIdleTime",
|
||||
"namespace": "AWS/EBS",
|
||||
@ -767,7 +760,6 @@
|
||||
"VolumeId": "$volume"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "VolumeQueueLength",
|
||||
"namespace": "AWS/EBS",
|
||||
@ -863,7 +855,6 @@
|
||||
"VolumeId": "$volume"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "BurstBalance",
|
||||
"namespace": "AWS/EBS",
|
||||
|
@ -95,7 +95,6 @@
|
||||
"FunctionName": "$function"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "Invocations",
|
||||
"namespace": "AWS/Lambda",
|
||||
@ -191,7 +190,6 @@
|
||||
"FunctionName": "$function"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "Duration",
|
||||
"namespace": "AWS/Lambda",
|
||||
@ -287,7 +285,6 @@
|
||||
"FunctionName": "$function"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "Errors",
|
||||
"namespace": "AWS/Lambda",
|
||||
@ -383,7 +380,6 @@
|
||||
"FunctionName": "$function"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "Throttles",
|
||||
"namespace": "AWS/Lambda",
|
||||
|
@ -95,7 +95,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "CPUUtilization",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -191,7 +190,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "DiskReadBytes",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -287,7 +285,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "DiskReadOps",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -383,7 +380,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "DiskWriteOps",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -479,7 +475,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "DiskWriteOps",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -575,7 +570,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "Network In",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -671,7 +665,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "NetworkOut",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -767,7 +760,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "NetworkPacketsIn",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -864,7 +856,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "StatusCheckFailed",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -961,7 +952,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "StatusCheckFailed_Instance",
|
||||
"namespace": "AWS/EC2",
|
||||
@ -1058,7 +1048,6 @@
|
||||
"InstanceId": "$instance"
|
||||
},
|
||||
"expression": "",
|
||||
"highResolution": false,
|
||||
"matchExact": true,
|
||||
"metricName": "StatusCheckFailed_System",
|
||||
"namespace": "AWS/EC2",
|
||||
|
@ -130,32 +130,28 @@ export default class CloudWatchDatasource extends DataSourceApi<CloudWatchQuery,
|
||||
|
||||
getPeriod(target: any, options: any, now?: number) {
|
||||
const start = this.convertToCloudWatchTime(options.range.from, false);
|
||||
const end = this.convertToCloudWatchTime(options.range.to, true);
|
||||
now = Math.round((now || Date.now()) / 1000);
|
||||
|
||||
let period;
|
||||
const range = end - start;
|
||||
|
||||
const hourSec = 60 * 60;
|
||||
const daySec = hourSec * 24;
|
||||
let periodUnit = 60;
|
||||
if (!target.period) {
|
||||
if (now - start <= daySec * 15) {
|
||||
// until 15 days ago
|
||||
if (target.namespace === 'AWS/EC2') {
|
||||
periodUnit = period = 300;
|
||||
period = 300;
|
||||
} else {
|
||||
periodUnit = period = 60;
|
||||
period = 60;
|
||||
}
|
||||
} else if (now - start <= daySec * 63) {
|
||||
// until 63 days ago
|
||||
periodUnit = period = 60 * 5;
|
||||
period = 60 * 5;
|
||||
} else if (now - start <= daySec * 455) {
|
||||
// until 455 days ago
|
||||
periodUnit = period = 60 * 60;
|
||||
period = 60 * 60;
|
||||
} else {
|
||||
// over 455 days, should return error, but try to long period
|
||||
periodUnit = period = 60 * 60;
|
||||
period = 60 * 60;
|
||||
}
|
||||
} else {
|
||||
period = this.templateSrv.replace(target.period, options.scopedVars);
|
||||
@ -168,9 +164,6 @@ export default class CloudWatchDatasource extends DataSourceApi<CloudWatchQuery,
|
||||
if (period < 1) {
|
||||
period = 1;
|
||||
}
|
||||
if (!target.highResolution && range / period >= 1440) {
|
||||
period = Math.ceil(range / 1440 / periodUnit) * periodUnit;
|
||||
}
|
||||
|
||||
return period;
|
||||
}
|
||||
@ -289,6 +282,10 @@ export default class CloudWatchDatasource extends DataSourceApi<CloudWatchQuery,
|
||||
regionsAffected.forEach(region => this.debouncedAlert(this.datasourceName, this.getActualRegion(region)));
|
||||
}
|
||||
|
||||
if (err.data && err.data.message === 'Metric request error' && err.data.error) {
|
||||
err.data.message = err.data.error;
|
||||
}
|
||||
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
@ -126,16 +126,6 @@
|
||||
</ul>
|
||||
</info-popover>
|
||||
</div>
|
||||
<div class="gf-form ">
|
||||
<gf-form-switch
|
||||
class="gf-form "
|
||||
label="HighRes "
|
||||
label-class="width-5 "
|
||||
checked="target.highResolution "
|
||||
on-change="onChange()"
|
||||
>
|
||||
</gf-form-switch>
|
||||
</div>
|
||||
|
||||
<div class="gf-form gf-form--grow ">
|
||||
<div class="gf-form-label gf-form-label--grow "></div>
|
||||
|
@ -17,7 +17,6 @@ export class CloudWatchQueryParameterCtrl {
|
||||
target.region = target.region || 'default';
|
||||
target.id = target.id || '';
|
||||
target.expression = target.expression || '';
|
||||
target.highResolution = target.highResolution || false;
|
||||
|
||||
$scope.regionSegment = uiSegmentSrv.getSegmentForValue($scope.target.region, 'select region');
|
||||
$scope.namespaceSegment = uiSegmentSrv.getSegmentForValue($scope.target.namespace, 'select namespace');
|
||||
|
@ -801,7 +801,7 @@ describe('CloudWatchDatasource', () => {
|
||||
{ period: '1', namespace: 'CustomMetricsNamespace' },
|
||||
{ range: { from: new Date(start), to: new Date(start + 3600 * 1000) } },
|
||||
hourSec * 3 - 1,
|
||||
60,
|
||||
1,
|
||||
],
|
||||
[
|
||||
{ period: '60s', namespace: 'CustomMetricsNamespace' },
|
||||
|
@ -10,7 +10,6 @@ export interface CloudWatchQuery extends DataQuery {
|
||||
period: string;
|
||||
expression: string;
|
||||
alias: string;
|
||||
highResolution: boolean;
|
||||
matchExact: boolean;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user