Alerting: Recording rules appear as type=recording in Prometheus API + better abstraction for type (#88805)

* Wire status through to prom API

* Regenerate swagger
This commit is contained in:
Alexander Weaver 2024-06-07 11:24:06 -05:00 committed by GitHub
parent b761153812
commit 58fdb24b0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 65 additions and 134 deletions

View File

@ -451,7 +451,7 @@ func toRuleGroup(log log.Logger, manager state.AlertInstanceManager, groupKey ng
Name: rule.Title,
Labels: rule.GetLabels(labelOptions...),
Health: "ok",
Type: apiv1.RuleTypeAlerting,
Type: rule.Type().String(),
LastEvaluation: time.Time{},
}

View File

@ -341,7 +341,7 @@ func (srv *ProvisioningSrv) RoutePostAlertRule(c *contextmodel.ReqContext, ar de
return ErrResp(http.StatusBadRequest, err, "")
}
if upstreamModel.IsRecordingRule() && !srv.featureManager.IsEnabledGlobally(featuremgmt.FlagGrafanaManagedRecordingRules) {
if upstreamModel.Type() == alerting_models.RuleTypeRecording && !srv.featureManager.IsEnabledGlobally(featuremgmt.FlagGrafanaManagedRecordingRules) {
return ErrResp(
http.StatusBadRequest,
fmt.Errorf("%w: recording rules cannot be created on this instance", alerting_models.ErrAlertRuleFailedValidation),
@ -377,7 +377,7 @@ func (srv *ProvisioningSrv) RoutePutAlertRule(c *contextmodel.ReqContext, ar def
ErrResp(http.StatusBadRequest, err, "")
}
if updated.IsRecordingRule() && !srv.featureManager.IsEnabledGlobally(featuremgmt.FlagGrafanaManagedRecordingRules) {
if updated.Type() == alerting_models.RuleTypeRecording && !srv.featureManager.IsEnabledGlobally(featuremgmt.FlagGrafanaManagedRecordingRules) {
return ErrResp(
http.StatusBadRequest,
fmt.Errorf("%w: recording rules cannot be created on this instance", alerting_models.ErrAlertRuleFailedValidation),

View File

@ -478,7 +478,7 @@
"type": "object"
},
"type": {
"$ref": "#/definitions/RuleType"
"type": "string"
}
},
"required": [
@ -3479,7 +3479,7 @@
"type": "string"
},
"type": {
"$ref": "#/definitions/RuleType"
"type": "string"
}
},
"required": [
@ -3597,10 +3597,6 @@
],
"type": "object"
},
"RuleType": {
"title": "RuleType models the type of a rule.",
"type": "string"
},
"SNSConfig": {
"properties": {
"api_url": {
@ -4668,7 +4664,6 @@
"type": "object"
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
"items": {
"$ref": "#/definitions/gettableAlert",
"type": "object"
@ -4743,6 +4738,31 @@
},
"type": "array"
},
"gettableGrafanaSilence": {
"properties": {
"accessControl": {
"additionalProperties": {
"type": "boolean"
},
"example": {
"create": false,
"read": true,
"write": false
},
"type": "object"
},
"metadata": {
"$ref": "#/definitions/SilenceMetadata"
}
},
"type": "object"
},
"gettableGrafanaSilences": {
"items": {
"$ref": "#/definitions/gettableGrafanaSilence"
},
"type": "array"
},
"gettableSilence": {
"description": "GettableSilence gettable silence",
"properties": {

View File

@ -172,9 +172,9 @@ type Rule struct {
Health string `json:"health"`
LastError string `json:"lastError,omitempty"`
// required: true
Type v1.RuleType `json:"type"`
LastEvaluation time.Time `json:"lastEvaluation"`
EvaluationTime float64 `json:"evaluationTime"`
Type string `json:"type"`
LastEvaluation time.Time `json:"lastEvaluation"`
EvaluationTime float64 `json:"evaluationTime"`
}
// Alert has info for an alert.

View File

@ -478,7 +478,7 @@
"type": "object"
},
"type": {
"$ref": "#/definitions/RuleType"
"type": "string"
}
},
"required": [
@ -3476,7 +3476,7 @@
"type": "string"
},
"type": {
"$ref": "#/definitions/RuleType"
"type": "string"
}
},
"required": [
@ -3594,10 +3594,6 @@
],
"type": "object"
},
"RuleType": {
"title": "RuleType models the type of a rule.",
"type": "string"
},
"SNSConfig": {
"properties": {
"api_url": {
@ -4503,6 +4499,7 @@
"type": "object"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"items": {
"$ref": "#/definitions/alertGroup",
"type": "object"

View File

@ -4040,7 +4040,7 @@
}
},
"type": {
"$ref": "#/definitions/RuleType"
"type": "string"
}
}
},
@ -7037,7 +7037,7 @@
"type": "string"
},
"type": {
"$ref": "#/definitions/RuleType"
"type": "string"
}
}
},
@ -7148,10 +7148,6 @@
}
}
},
"RuleType": {
"type": "string",
"title": "RuleType models the type of a rule."
},
"SNSConfig": {
"type": "object",
"properties": {

View File

@ -103,6 +103,17 @@ const (
KeepLastErrState ExecutionErrorState = "KeepLast"
)
type RuleType string
const (
RuleTypeAlerting = "alerting"
RuleTypeRecording = "recording"
)
func (r RuleType) String() string {
return string(r)
}
const (
// Annotations are actually a set of labels, so technically this is the label name of an annotation.
DashboardUIDAnnotation = "__dashboardUid__"
@ -344,7 +355,7 @@ func (alertRule *AlertRule) GetLabels(opts ...LabelOption) map[string]string {
}
func (alertRule *AlertRule) GetEvalCondition() Condition {
if alertRule.IsRecordingRule() {
if alertRule.Type() == RuleTypeRecording {
return Condition{
Condition: alertRule.Record.From,
Data: alertRule.Data,
@ -512,7 +523,7 @@ func (alertRule *AlertRule) ValidateAlertRule(cfg setting.UnifiedAlertingSetting
}
var err error
if alertRule.IsRecordingRule() {
if alertRule.Type() == RuleTypeRecording {
err = validateRecordingRuleFields(alertRule)
} else {
err = validateAlertRuleFields(alertRule)
@ -586,8 +597,11 @@ func (alertRule *AlertRule) GetFolderKey() FolderKey {
}
}
func (alertRule *AlertRule) IsRecordingRule() bool {
return alertRule.Record != nil
func (alertRule *AlertRule) Type() RuleType {
if alertRule.Record != nil {
return RuleTypeRecording
}
return RuleTypeAlerting
}
// AlertRuleVersion is the model for alert rule versions in unified alerting.

View File

@ -62,7 +62,7 @@ func newRuleFactory(
stopAppliedHook stopAppliedFunc,
) ruleFactoryFunc {
return func(ctx context.Context, rule *ngmodels.AlertRule) Rule {
if rule.IsRecordingRule() {
if rule.Type() == ngmodels.RuleTypeRecording {
return newRecordingRule(
ctx,
maxAttempts,

View File

@ -189,7 +189,7 @@ func (r *recordingRule) tryEvaluation(ctx context.Context, ev *Evaluation, logge
return fmt.Errorf("server side expressions pipeline returned an error: %w", err)
}
logger.Debug("Alert rule evaluated", "results", result, "duration", evalDur)
logger.Info("Recording rule evaluated", "results", result, "duration", evalDur)
span.AddEvent("rule evaluated", trace.WithAttributes(
attribute.Int64("results", int64(len(result.Responses))),
))

View File

@ -693,7 +693,7 @@ func TestIntegrationInsertAlertRules(t *testing.T) {
t.Run("inserted alerting rules should have nil recording rule fields on model", func(t *testing.T) {
for _, rule := range dbRules {
if !rule.IsRecordingRule() {
if rule.Type() == models.RuleTypeAlerting {
require.Nil(t, rule.Record)
}
}
@ -701,7 +701,7 @@ func TestIntegrationInsertAlertRules(t *testing.T) {
t.Run("inserted recording rules map identical fields when listed", func(t *testing.T) {
for _, rule := range dbRules {
if rule.IsRecordingRule() {
if rule.Type() == models.RuleTypeRecording {
require.NotNil(t, rule.Record)
require.Equal(t, "my_metric", rule.Record.Metric)
require.Equal(t, "A", rule.Record.From)
@ -711,7 +711,7 @@ func TestIntegrationInsertAlertRules(t *testing.T) {
t.Run("inserted recording rules have empty or default alert-specific settings", func(t *testing.T) {
for _, rule := range dbRules {
if rule.IsRecordingRule() {
if rule.Type() == models.RuleTypeRecording {
require.Empty(t, rule.Condition)
require.Equal(t, models.NoDataState(""), rule.NoDataState)
require.Equal(t, models.ExecutionErrorState(""), rule.ExecErrState)

View File

@ -12476,7 +12476,7 @@
}
},
"type": {
"$ref": "#/definitions/RuleType"
"type": "string"
}
}
},
@ -19148,7 +19148,7 @@
"type": "string"
},
"type": {
"$ref": "#/definitions/RuleType"
"type": "string"
}
}
},
@ -19259,10 +19259,6 @@
}
}
},
"RuleType": {
"type": "string",
"title": "RuleType models the type of a rule."
},
"SNSConfig": {
"type": "object",
"properties": {
@ -21749,7 +21745,6 @@
}
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
"type": "array",
"items": {
"type": "object",
@ -21758,16 +21753,6 @@
},
"gettableGrafanaSilence": {
"type": "object",
"required": [
"comment",
"createdBy",
"endsAt",
"matchers",
"startsAt",
"id",
"status",
"updatedAt"
],
"properties": {
"accessControl": {
"type": "object",
@ -21780,41 +21765,8 @@
"write": false
}
},
"comment": {
"description": "comment",
"type": "string"
},
"createdBy": {
"description": "created by",
"type": "string"
},
"endsAt": {
"description": "ends at",
"type": "string",
"format": "date-time"
},
"id": {
"description": "id",
"type": "string"
},
"matchers": {
"$ref": "#/definitions/matchers"
},
"metadata": {
"$ref": "#/definitions/SilenceMetadata"
},
"startsAt": {
"description": "starts at",
"type": "string",
"format": "date-time"
},
"status": {
"$ref": "#/definitions/silenceStatus"
},
"updatedAt": {
"description": "updated at",
"type": "string",
"format": "date-time"
}
}
},

View File

@ -2845,7 +2845,7 @@
"type": "object"
},
"type": {
"$ref": "#/components/schemas/RuleType"
"type": "string"
}
},
"required": [
@ -9520,7 +9520,7 @@
"type": "string"
},
"type": {
"$ref": "#/components/schemas/RuleType"
"type": "string"
}
},
"required": [
@ -9638,10 +9638,6 @@
],
"type": "object"
},
"RuleType": {
"title": "RuleType models the type of a rule.",
"type": "string"
},
"SNSConfig": {
"properties": {
"api_url": {
@ -12126,7 +12122,6 @@
"type": "object"
},
"gettableAlerts": {
"description": "GettableAlerts gettable alerts",
"items": {
"$ref": "#/components/schemas/gettableAlert"
},
@ -12145,53 +12140,10 @@
},
"type": "object"
},
"comment": {
"description": "comment",
"type": "string"
},
"createdBy": {
"description": "created by",
"type": "string"
},
"endsAt": {
"description": "ends at",
"format": "date-time",
"type": "string"
},
"id": {
"description": "id",
"type": "string"
},
"matchers": {
"$ref": "#/components/schemas/matchers"
},
"metadata": {
"$ref": "#/components/schemas/SilenceMetadata"
},
"startsAt": {
"description": "starts at",
"format": "date-time",
"type": "string"
},
"status": {
"$ref": "#/components/schemas/silenceStatus"
},
"updatedAt": {
"description": "updated at",
"format": "date-time",
"type": "string"
}
},
"required": [
"comment",
"createdBy",
"endsAt",
"matchers",
"startsAt",
"id",
"status",
"updatedAt"
],
"type": "object"
},
"gettableGrafanaSilences": {