feat(alerting): add async state persister (#80763)

This commit is contained in:
Jean-Philippe Quéméner
2024-01-22 13:07:11 +01:00
committed by GitHub
parent a7e9408433
commit eb7e1216a1
7 changed files with 313 additions and 0 deletions
@@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
// ListAlertInstances is a handler for retrieving alert instances within specific organisation
@@ -197,3 +198,36 @@ func (st DBstore) DeleteAlertInstancesByRule(ctx context.Context, key models.Ale
return err
})
}
func (st DBstore) FullSync(ctx context.Context, instances []models.AlertInstance) error {
if len(instances) == 0 {
return nil
}
return st.SQLStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
// First we delete all records from the table
if _, err := sess.Exec("DELETE FROM alert_instance"); err != nil {
return fmt.Errorf("failed to delete alert_instance table: %w", err)
}
for _, alertInstance := range instances {
if err := models.ValidateAlertInstance(alertInstance); err != nil {
st.Logger.Warn("Failed to validate alert instance, skipping", "err", err, "rule_uid", alertInstance.RuleUID)
continue
}
labelTupleJSON, err := alertInstance.Labels.StringKey()
if err != nil {
st.Logger.Warn("Failed to generate alert instance labels key, skipping", "err", err, "rule_uid", alertInstance.RuleUID)
continue
}
_, err = sess.Exec("INSERT INTO alert_instance (rule_org_id, rule_uid, labels, labels_hash, current_state, current_reason, current_state_since, current_state_end, last_eval_time) VALUES (?,?,?,?,?,?,?,?,?)",
alertInstance.RuleOrgID, alertInstance.RuleUID, labelTupleJSON, alertInstance.LabelsHash, alertInstance.CurrentState, alertInstance.CurrentReason, alertInstance.CurrentStateSince.Unix(), alertInstance.CurrentStateEnd.Unix(), alertInstance.LastEvalTime.Unix())
if err != nil {
return fmt.Errorf("failed to insert into alert_instance table: %w", err)
}
}
if err := sess.Commit(); err != nil {
return fmt.Errorf("failed to commit alert_instance table: %w", err)
}
return nil
})
}