mirror of https://github.com/grafana/grafana
GoogleCloudMonitoring: Refactor SLO queries (#59421)
* GoogleCloudMonitoring: Refactor metricType input * Remove preprocessor in favor of secondary inputs * GoogleCloudMonitoring: Refactor SLO queries * GoogleCloudMonitoring: Refactor util functions (#59482) * GoogleCloudMonitoring: Remove unnecessary util functions * GoogleCloudMonitoring: Refactor run function (#59505)pull/59600/head
parent
4ec08c4317
commit
2e64ea652e
@ -0,0 +1,75 @@ |
|||||||
|
package cloudmonitoring |
||||||
|
|
||||||
|
import ( |
||||||
|
"context" |
||||||
|
"fmt" |
||||||
|
"net/url" |
||||||
|
"time" |
||||||
|
|
||||||
|
"github.com/grafana/grafana-plugin-sdk-go/backend" |
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/tracing" |
||||||
|
) |
||||||
|
|
||||||
|
func (sloQ *cloudMonitoringSLO) run(ctx context.Context, req *backend.QueryDataRequest, |
||||||
|
s *Service, dsInfo datasourceInfo, tracer tracing.Tracer) (*backend.DataResponse, cloudMonitoringResponse, string, error) { |
||||||
|
return runTimeSeriesRequest(ctx, sloQ.logger, req, s, dsInfo, tracer, sloQ.parameters.ProjectName, sloQ.params, nil) |
||||||
|
} |
||||||
|
|
||||||
|
func (sloQ *cloudMonitoringSLO) parseResponse(queryRes *backend.DataResponse, |
||||||
|
response cloudMonitoringResponse, executedQueryString string) error { |
||||||
|
return parseTimeSeriesResponse(queryRes, response, executedQueryString, sloQ, sloQ.params, []string{}) |
||||||
|
} |
||||||
|
|
||||||
|
func (sloQ *cloudMonitoringSLO) buildDeepLink() string { |
||||||
|
return "" |
||||||
|
} |
||||||
|
|
||||||
|
func (sloQ *cloudMonitoringSLO) getRefID() string { |
||||||
|
return sloQ.refID |
||||||
|
} |
||||||
|
|
||||||
|
func (sloQ *cloudMonitoringSLO) getAliasBy() string { |
||||||
|
return sloQ.aliasBy |
||||||
|
} |
||||||
|
|
||||||
|
func (sloQ *cloudMonitoringSLO) getParameter(i string) string { |
||||||
|
switch i { |
||||||
|
case "project": |
||||||
|
return sloQ.parameters.ProjectName |
||||||
|
case "service": |
||||||
|
return sloQ.parameters.ServiceId |
||||||
|
case "slo": |
||||||
|
return sloQ.parameters.SloId |
||||||
|
case "selector": |
||||||
|
return sloQ.parameters.SelectorName |
||||||
|
default: |
||||||
|
return "" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (sloQ *cloudMonitoringSLO) getFilter() string { |
||||||
|
sloName := fmt.Sprintf("projects/%s/services/%s/serviceLevelObjectives/%s", sloQ.parameters.ProjectName, sloQ.parameters.ServiceId, sloQ.parameters.SloId) |
||||||
|
|
||||||
|
if sloQ.parameters.SelectorName == "select_slo_burn_rate" { |
||||||
|
return fmt.Sprintf(`%s("%s", "%s")`, sloQ.parameters.SelectorName, sloName, sloQ.parameters.LookbackPeriod) |
||||||
|
} else { |
||||||
|
return fmt.Sprintf(`%s("%s")`, sloQ.parameters.SelectorName, sloName) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func (sloQ *cloudMonitoringSLO) setParams(startTime time.Time, endTime time.Time, durationSeconds int, intervalMs int64) { |
||||||
|
params := url.Values{} |
||||||
|
|
||||||
|
params.Add("interval.startTime", startTime.UTC().Format(time.RFC3339)) |
||||||
|
params.Add("interval.endTime", endTime.UTC().Format(time.RFC3339)) |
||||||
|
|
||||||
|
params.Add("filter", sloQ.getFilter()) |
||||||
|
params.Add("aggregation.alignmentPeriod", calculateAlignmentPeriod(sloQ.parameters.AlignmentPeriod, intervalMs, durationSeconds)) |
||||||
|
if sloQ.parameters.SelectorName == "select_slo_health" { |
||||||
|
params.Add("aggregation.perSeriesAligner", "ALIGN_MEAN") |
||||||
|
} else { |
||||||
|
params.Add("aggregation.perSeriesAligner", "ALIGN_NEXT_OLDER") |
||||||
|
} |
||||||
|
sloQ.params = params |
||||||
|
} |
||||||
@ -0,0 +1,75 @@ |
|||||||
|
package cloudmonitoring |
||||||
|
|
||||||
|
import ( |
||||||
|
"net/url" |
||||||
|
"testing" |
||||||
|
|
||||||
|
"github.com/grafana/grafana-plugin-sdk-go/backend" |
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert" |
||||||
|
"github.com/stretchr/testify/require" |
||||||
|
) |
||||||
|
|
||||||
|
func SLOQuery(t *testing.T) { |
||||||
|
t.Run("when data from query returns slo and alias by is defined", func(t *testing.T) { |
||||||
|
data, err := loadTestFile("./test-data/6-series-response-slo.json") |
||||||
|
require.NoError(t, err) |
||||||
|
assert.Equal(t, 1, len(data.TimeSeries)) |
||||||
|
|
||||||
|
t.Run("and alias by is expanded", func(t *testing.T) { |
||||||
|
res := &backend.DataResponse{} |
||||||
|
query := &cloudMonitoringSLO{ |
||||||
|
params: url.Values{}, |
||||||
|
parameters: &sloQuery{ |
||||||
|
ProjectName: "test-proj", |
||||||
|
SelectorName: "select_slo_compliance", |
||||||
|
ServiceId: "test-service", |
||||||
|
SloId: "test-slo", |
||||||
|
}, |
||||||
|
aliasBy: "{{project}} - {{service}} - {{slo}} - {{selector}}", |
||||||
|
} |
||||||
|
err = query.parseResponse(res, data, "") |
||||||
|
require.NoError(t, err) |
||||||
|
frames := res.Frames |
||||||
|
require.NoError(t, err) |
||||||
|
assert.Equal(t, "test-proj - test-service - test-slo - select_slo_compliance", frames[0].Fields[1].Name) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
t.Run("when data from query returns slo and alias by is not defined", func(t *testing.T) { |
||||||
|
data, err := loadTestFile("./test-data/6-series-response-slo.json") |
||||||
|
require.NoError(t, err) |
||||||
|
assert.Equal(t, 1, len(data.TimeSeries)) |
||||||
|
|
||||||
|
t.Run("and alias by is expanded", func(t *testing.T) { |
||||||
|
res := &backend.DataResponse{} |
||||||
|
query := &cloudMonitoringSLO{ |
||||||
|
params: url.Values{}, |
||||||
|
parameters: &sloQuery{ |
||||||
|
ProjectName: "test-proj", |
||||||
|
SelectorName: "select_slo_compliance", |
||||||
|
ServiceId: "test-service", |
||||||
|
SloId: "test-slo", |
||||||
|
}, |
||||||
|
} |
||||||
|
err = query.parseResponse(res, data, "") |
||||||
|
require.NoError(t, err) |
||||||
|
frames := res.Frames |
||||||
|
require.NoError(t, err) |
||||||
|
assert.Equal(t, "select_slo_compliance(\"projects/test-proj/services/test-service/serviceLevelObjectives/test-slo\")", frames[0].Fields[1].Name) |
||||||
|
}) |
||||||
|
}) |
||||||
|
|
||||||
|
t.Run("when data comes from a slo query, it should skip the link", func(t *testing.T) { |
||||||
|
data, err := loadTestFile("./test-data/3-series-response-distribution-exponential.json") |
||||||
|
require.NoError(t, err) |
||||||
|
assert.Equal(t, 1, len(data.TimeSeries)) |
||||||
|
|
||||||
|
res := &backend.DataResponse{} |
||||||
|
query := &cloudMonitoringSLO{params: url.Values{}, parameters: &sloQuery{SloId: "yes"}} |
||||||
|
err = query.parseResponse(res, data, "") |
||||||
|
require.NoError(t, err) |
||||||
|
frames := res.Frames |
||||||
|
assert.Equal(t, len(frames[0].Fields[1].Config.Links), 0) |
||||||
|
}) |
||||||
|
} |
||||||
Loading…
Reference in new issue