diff --git a/dev/managedservicesplatform/internal/resource/alertpolicy/BUILD.bazel b/dev/managedservicesplatform/internal/resource/alertpolicy/BUILD.bazel index 45dd352aba5..9204dcba39d 100644 --- a/dev/managedservicesplatform/internal/resource/alertpolicy/BUILD.bazel +++ b/dev/managedservicesplatform/internal/resource/alertpolicy/BUILD.bazel @@ -29,6 +29,7 @@ go_test( name = "alertpolicy_test", srcs = [ "conditionbuilder_test.go", + "customalert_test.go", "responsecode_test.go", ], embed = [":alertpolicy"], diff --git a/dev/managedservicesplatform/internal/resource/alertpolicy/customalert.go b/dev/managedservicesplatform/internal/resource/alertpolicy/customalert.go index 04beac6a606..5f7ac9bc933 100644 --- a/dev/managedservicesplatform/internal/resource/alertpolicy/customalert.go +++ b/dev/managedservicesplatform/internal/resource/alertpolicy/customalert.go @@ -1,6 +1,9 @@ package alertpolicy import ( + "fmt" + "strings" + "github.com/sourcegraph/managed-services-platform-cdktf/gen/google/monitoringalertpolicy" "github.com/sourcegraph/sourcegraph/dev/managedservicesplatform/spec" @@ -26,11 +29,18 @@ func newCustomAlertCondition(config *Config) *monitoringalertpolicy.MonitoringAl return &monitoringalertpolicy.MonitoringAlertPolicyConditions{ DisplayName: pointers.Ptr(config.Name), ConditionPrometheusQueryLanguage: &monitoringalertpolicy.MonitoringAlertPolicyConditionsConditionPrometheusQueryLanguage{ - Query: pointers.Ptr(config.CustomAlert.Query), + Query: pointers.Ptr(flattenPromQLQuery(config.CustomAlert.Query)), Duration: pointers.Stringf("%ds", *config.CustomAlert.DurationMinutes*60), }, } + default: + panic(fmt.Sprintf("unknown custom alert type %q", config.CustomAlert.Type)) } - - return nil +} + +// GCP monitoring expects PromQL queries to be on a single line, so we do that +// automatically and also strip extra spaces for readability of the condensed +// version. +func flattenPromQLQuery(query string) string { + return strings.Join(strings.Fields(strings.ReplaceAll(query, "\n", " ")), " ") } diff --git a/dev/managedservicesplatform/internal/resource/alertpolicy/customalert_test.go b/dev/managedservicesplatform/internal/resource/alertpolicy/customalert_test.go new file mode 100644 index 00000000000..3357f704ca6 --- /dev/null +++ b/dev/managedservicesplatform/internal/resource/alertpolicy/customalert_test.go @@ -0,0 +1,53 @@ +package alertpolicy + +import ( + "testing" + + "github.com/hexops/autogold/v2" +) + +func TestFlattenPromQLQuery(t *testing.T) { + for _, tc := range []struct { + name string + query string + want autogold.Value + }{{ + name: "simple query", + query: "sum(rate(foo[1m]))", + want: autogold.Expect("sum(rate(foo[1m]))"), + }, { + name: "complex query", + query: ` ( + sum by (rpc_error_service_method) ( + label_join( + rate(workload_googleapis_com:rpc_server_requests_per_rpc_count{ + monitored_resource="generic_task", + rpc_connect_rpc_error_code!="" + }[30m]), + "rpc_error_service_method", + "/", + "rpc_connect_rpc_error_code", "rpc_service", "rpc_method" + ) + ) + / + ignoring(rpc_error_service_method) group_left + sum by (rpc_error_service_method) ( + label_join( + rate(workload_googleapis_com:rpc_server_requests_per_rpc_count{ + monitored_resource="generic_task", + rpc_connect_rpc_error_code="" + }[30m]), + "rpc_service_method_error", + "/", + "rpc_service", "rpc_method", "rpc_connect_rpc_error_code" + ) + ) + ) > 0.2`, + want: autogold.Expect(`( sum by (rpc_error_service_method) ( label_join( rate(workload_googleapis_com:rpc_server_requests_per_rpc_count{ monitored_resource="generic_task", rpc_connect_rpc_error_code!="" }[30m]), "rpc_error_service_method", "/", "rpc_connect_rpc_error_code", "rpc_service", "rpc_method" ) ) / ignoring(rpc_error_service_method) group_left sum by (rpc_error_service_method) ( label_join( rate(workload_googleapis_com:rpc_server_requests_per_rpc_count{ monitored_resource="generic_task", rpc_connect_rpc_error_code="" }[30m]), "rpc_service_method_error", "/", "rpc_service", "rpc_method", "rpc_connect_rpc_error_code" ) ) ) > 0.2`), + }} { + t.Run(tc.name, func(t *testing.T) { + got := flattenPromQLQuery(tc.query) + tc.want.Equal(t, got) + }) + } +}