Commit a5e5db20 by Daniel Lee

azuremonitor: add support for aggregations on backend

parent 10194df1
...@@ -256,7 +256,21 @@ func (e *AzureMonitorExecutor) parseResponse(queryRes *tsdb.QueryResult, data Az ...@@ -256,7 +256,21 @@ func (e *AzureMonitorExecutor) parseResponse(queryRes *tsdb.QueryResult, data Az
defaultMetricName := fmt.Sprintf("%s.%s", query.UrlComponents["resourceName"], series.Name.LocalizedValue) defaultMetricName := fmt.Sprintf("%s.%s", query.UrlComponents["resourceName"], series.Name.LocalizedValue)
for _, point := range series.Timeseries[0].Data { for _, point := range series.Timeseries[0].Data {
value := point.Average var value float64
switch query.Params.Get("aggregation") {
case "Average":
value = point.Average
case "Total":
value = point.Total
case "Maximum":
value = point.Maximum
case "Minimum":
value = point.Minimum
case "Count":
value = point.Count
default:
value = point.Count
}
points = append(points, tsdb.NewTimePoint(null.FloatFrom(value), float64((point.TimeStamp).Unix())*1000)) points = append(points, tsdb.NewTimePoint(null.FloatFrom(value), float64((point.TimeStamp).Unix())*1000))
} }
......
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/url"
"testing" "testing"
"time" "time"
...@@ -61,8 +62,8 @@ func TestAzureMonitor(t *testing.T) { ...@@ -61,8 +62,8 @@ func TestAzureMonitor(t *testing.T) {
}) })
Convey("Parse AzureMonitor API response in the time series format", func() { Convey("Parse AzureMonitor API response in the time series format", func() {
Convey("when data from query aggregated to one time series", func() { Convey("when data from query aggregated as average to one time series", func() {
data, err := loadTestFile("./test-data/1-azure-monitor-response.json") data, err := loadTestFile("./test-data/1-azure-monitor-response-avg.json")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(data.Interval, ShouldEqual, "PT1M") So(data.Interval, ShouldEqual, "PT1M")
...@@ -71,6 +72,9 @@ func TestAzureMonitor(t *testing.T) { ...@@ -71,6 +72,9 @@ func TestAzureMonitor(t *testing.T) {
UrlComponents: map[string]string{ UrlComponents: map[string]string{
"resourceName": "grafana", "resourceName": "grafana",
}, },
Params: url.Values{
"aggregation": {"Average"},
},
} }
err = executor.parseResponse(res, data, query) err = executor.parseResponse(res, data, query)
So(err, ShouldBeNil) So(err, ShouldBeNil)
...@@ -78,6 +82,101 @@ func TestAzureMonitor(t *testing.T) { ...@@ -78,6 +82,101 @@ func TestAzureMonitor(t *testing.T) {
So(len(res.Series), ShouldEqual, 1) So(len(res.Series), ShouldEqual, 1)
So(res.Series[0].Name, ShouldEqual, "grafana.Percentage CPU") So(res.Series[0].Name, ShouldEqual, "grafana.Percentage CPU")
So(len(res.Series[0].Points), ShouldEqual, 5) So(len(res.Series[0].Points), ShouldEqual, 5)
So(res.Series[0].Points[0][0].Float64, ShouldEqual, 2.0875)
So(res.Series[0].Points[0][1].Float64, ShouldEqual, 1549620780000)
So(res.Series[0].Points[1][0].Float64, ShouldEqual, 2.1525)
So(res.Series[0].Points[1][1].Float64, ShouldEqual, 1549620840000)
So(res.Series[0].Points[2][0].Float64, ShouldEqual, 2.155)
So(res.Series[0].Points[2][1].Float64, ShouldEqual, 1549620900000)
So(res.Series[0].Points[3][0].Float64, ShouldEqual, 3.6925)
So(res.Series[0].Points[3][1].Float64, ShouldEqual, 1549620960000)
So(res.Series[0].Points[4][0].Float64, ShouldEqual, 2.44)
So(res.Series[0].Points[4][1].Float64, ShouldEqual, 1549621020000)
})
Convey("when data from query aggregated as total to one time series", func() {
data, err := loadTestFile("./test-data/2-azure-monitor-response-total.json")
So(err, ShouldBeNil)
res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
query := &AzureMonitorQuery{
UrlComponents: map[string]string{
"resourceName": "grafana",
},
Params: url.Values{
"aggregation": {"Total"},
},
}
err = executor.parseResponse(res, data, query)
So(err, ShouldBeNil)
So(res.Series[0].Points[0][0].Float64, ShouldEqual, 8.26)
So(res.Series[0].Points[0][1].Float64, ShouldEqual, 1549718940000)
})
Convey("when data from query aggregated as maximum to one time series", func() {
data, err := loadTestFile("./test-data/3-azure-monitor-response-maximum.json")
So(err, ShouldBeNil)
res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
query := &AzureMonitorQuery{
UrlComponents: map[string]string{
"resourceName": "grafana",
},
Params: url.Values{
"aggregation": {"Maximum"},
},
}
err = executor.parseResponse(res, data, query)
So(err, ShouldBeNil)
So(res.Series[0].Points[0][0].Float64, ShouldEqual, 3.07)
So(res.Series[0].Points[0][1].Float64, ShouldEqual, 1549722360000)
})
Convey("when data from query aggregated as minimum to one time series", func() {
data, err := loadTestFile("./test-data/4-azure-monitor-response-minimum.json")
So(err, ShouldBeNil)
res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
query := &AzureMonitorQuery{
UrlComponents: map[string]string{
"resourceName": "grafana",
},
Params: url.Values{
"aggregation": {"Minimum"},
},
}
err = executor.parseResponse(res, data, query)
So(err, ShouldBeNil)
So(res.Series[0].Points[0][0].Float64, ShouldEqual, 1.51)
So(res.Series[0].Points[0][1].Float64, ShouldEqual, 1549723380000)
})
Convey("when data from query aggregated as Count to one time series", func() {
data, err := loadTestFile("./test-data/5-azure-monitor-response-count.json")
So(err, ShouldBeNil)
res := &tsdb.QueryResult{Meta: simplejson.New(), RefId: "A"}
query := &AzureMonitorQuery{
UrlComponents: map[string]string{
"resourceName": "grafana",
},
Params: url.Values{
"aggregation": {"Count"},
},
}
err = executor.parseResponse(res, data, query)
So(err, ShouldBeNil)
So(res.Series[0].Points[0][0].Float64, ShouldEqual, 4)
So(res.Series[0].Points[0][1].Float64, ShouldEqual, 1549723440000)
}) })
}) })
}) })
......
{
"cost": 0,
"timespan": "2019-02-09T13:29:41Z\/2019-02-09T19:29:41Z",
"interval": "PT1M",
"value": [
{
"id": "\/subscriptions\/44693801-6ee6-49de-9b2d-9106972f9572\/resourceGroups\/grafanastaging\/providers\/Microsoft.Compute\/virtualMachines\/grafana\/providers\/Microsoft.Insights\/metrics\/Percentage CPU",
"type": "Microsoft.Insights\/metrics",
"name": {
"value": "Percentage CPU",
"localizedValue": "Percentage CPU"
},
"unit": "Percent",
"timeseries": [
{
"metadatavalues": [
],
"data": [
{
"timeStamp": "2019-02-09T13:29:00Z",
"total": 8.26
},
{
"timeStamp": "2019-02-09T13:30:00Z",
"total": 8.7
},
{
"timeStamp": "2019-02-09T13:31:00Z",
"total": 14.82
},
{
"timeStamp": "2019-02-09T13:32:00Z",
"total": 10.07
},
{
"timeStamp": "2019-02-09T13:33:00Z",
"total": 8.52
}
]
}
]
}
],
"namespace": "Microsoft.Compute\/virtualMachines",
"resourceregion": "westeurope"
}
{
"cost": 0,
"timespan": "2019-02-09T14:26:12Z\/2019-02-09T20:26:12Z",
"interval": "PT1M",
"value": [
{
"id": "\/subscriptions\/44693801-6ee6-49de-9b2d-9106972f9572\/resourceGroups\/grafanastaging\/providers\/Microsoft.Compute\/virtualMachines\/grafana\/providers\/Microsoft.Insights\/metrics\/Percentage CPU",
"type": "Microsoft.Insights\/metrics",
"name": {
"value": "Percentage CPU",
"localizedValue": "Percentage CPU"
},
"unit": "Percent",
"timeseries": [
{
"metadatavalues": [
],
"data": [
{
"timeStamp": "2019-02-09T14:26:00Z",
"maximum": 3.07
},
{
"timeStamp": "2019-02-09T14:27:00Z",
"maximum": 2.92
},
{
"timeStamp": "2019-02-09T14:28:00Z",
"maximum": 2.87
},
{
"timeStamp": "2019-02-09T14:29:00Z",
"maximum": 2.27
},
{
"timeStamp": "2019-02-09T14:30:00Z",
"maximum": 2.52
}
]
}
]
}
],
"namespace": "Microsoft.Compute\/virtualMachines",
"resourceregion": "westeurope"
}
{
"cost": 0,
"timespan": "2019-02-09T14:43:21Z\/2019-02-09T20:43:21Z",
"interval": "PT1M",
"value": [
{
"id": "\/subscriptions\/44693801-6ee6-49de-9b2d-9106972f9572\/resourceGroups\/grafanastaging\/providers\/Microsoft.Compute\/virtualMachines\/grafana\/providers\/Microsoft.Insights\/metrics\/Percentage CPU",
"type": "Microsoft.Insights\/metrics",
"name": {
"value": "Percentage CPU",
"localizedValue": "Percentage CPU"
},
"unit": "Percent",
"timeseries": [
{
"metadatavalues": [
],
"data": [
{
"timeStamp": "2019-02-09T14:43:00Z",
"minimum": 1.51
},
{
"timeStamp": "2019-02-09T14:44:00Z",
"minimum": 2.38
},
{
"timeStamp": "2019-02-09T14:45:00Z",
"minimum": 1.69
},
{
"timeStamp": "2019-02-09T14:46:00Z",
"minimum": 2.27
},
{
"timeStamp": "2019-02-09T14:47:00Z",
"minimum": 1.96
}
]
}
]
}
],
"namespace": "Microsoft.Compute\/virtualMachines",
"resourceregion": "westeurope"
}
{
"cost": 0,
"timespan": "2019-02-09T14:44:52Z\/2019-02-09T20:44:52Z",
"interval": "PT1M",
"value": [
{
"id": "\/subscriptions\/44693801-6ee6-49de-9b2d-9106972f9572\/resourceGroups\/grafanastaging\/providers\/Microsoft.Compute\/virtualMachines\/grafana\/providers\/Microsoft.Insights\/metrics\/Percentage CPU",
"type": "Microsoft.Insights\/metrics",
"name": {
"value": "Percentage CPU",
"localizedValue": "Percentage CPU"
},
"unit": "Percent",
"timeseries": [
{
"metadatavalues": [
],
"data": [
{
"timeStamp": "2019-02-09T14:44:00Z",
"count": 4
},
{
"timeStamp": "2019-02-09T14:45:00Z",
"count": 4
},
{
"timeStamp": "2019-02-09T14:46:00Z",
"count": 4
},
{
"timeStamp": "2019-02-09T14:47:00Z",
"count": 4
},
{
"timeStamp": "2019-02-09T14:48:00Z",
"count": 4
}
]
}
]
}
],
"namespace": "Microsoft.Compute\/virtualMachines",
"resourceregion": "westeurope"
}
...@@ -39,7 +39,11 @@ type AzureMonitorResponse struct { ...@@ -39,7 +39,11 @@ type AzureMonitorResponse struct {
} `json:"metadatavalues"` } `json:"metadatavalues"`
Data []struct { Data []struct {
TimeStamp time.Time `json:"timeStamp"` TimeStamp time.Time `json:"timeStamp"`
Average float64 `json:"average"` Average float64 `json:"average,omitempty"`
Total float64 `json:"total,omitempty"`
Count float64 `json:"count,omitempty"`
Maximum float64 `json:"maximum,omitempty"`
Minimum float64 `json:"minimum,omitempty"`
} `json:"data"` } `json:"data"`
} `json:"timeseries"` } `json:"timeseries"`
} `json:"value"` } `json:"value"`
......
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