mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 03:09:26 +08:00
Alerting: Extend recording rule definitions/interfaces with data source. (#101678)
Extend the recording rule definition to include the target data source, allowing configuration of where the output of the recording rule is written to. Also extends the relevant interfaces in preparation for the next set of changes.
This commit is contained in:
@ -494,13 +494,21 @@ func NotificationSettingsFromAlertRuleNotificationSettings(ns *definitions.Alert
|
||||
}
|
||||
}
|
||||
|
||||
func pointerOmitEmpty(s string) *string {
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
return &s
|
||||
}
|
||||
|
||||
func AlertRuleRecordExportFromRecord(r *models.Record) *definitions.AlertRuleRecordExport {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
return &definitions.AlertRuleRecordExport{
|
||||
Metric: r.Metric,
|
||||
From: r.From,
|
||||
Metric: r.Metric,
|
||||
From: r.From,
|
||||
TargetDatasourceUID: pointerOmitEmpty(r.TargetDatasourceUID),
|
||||
}
|
||||
}
|
||||
|
||||
@ -509,8 +517,9 @@ func ModelRecordFromApiRecord(r *definitions.Record) *models.Record {
|
||||
return nil
|
||||
}
|
||||
return &models.Record{
|
||||
Metric: r.Metric,
|
||||
From: r.From,
|
||||
Metric: r.Metric,
|
||||
From: r.From,
|
||||
TargetDatasourceUID: r.TargetDatasourceUID,
|
||||
}
|
||||
}
|
||||
|
||||
@ -519,8 +528,9 @@ func ApiRecordFromModelRecord(r *models.Record) *definitions.Record {
|
||||
return nil
|
||||
}
|
||||
return &definitions.Record{
|
||||
Metric: r.Metric,
|
||||
From: r.From,
|
||||
Metric: r.Metric,
|
||||
From: r.From,
|
||||
TargetDatasourceUID: r.TargetDatasourceUID,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -533,6 +533,10 @@ type Record struct {
|
||||
// required: true
|
||||
// example: A
|
||||
From string `json:"from" yaml:"from"`
|
||||
// Which data source should be used to write the output of the recording rule, specified by UID.
|
||||
// required: false
|
||||
// example: my-prom
|
||||
TargetDatasourceUID string `json:"target_datasource_uid,omitempty" yaml:"target_datasource_uid,omitempty"`
|
||||
}
|
||||
|
||||
// swagger:model
|
||||
|
@ -308,6 +308,7 @@ type AlertRuleNotificationSettingsExport struct {
|
||||
|
||||
// Record is the provisioned export of models.Record.
|
||||
type AlertRuleRecordExport struct {
|
||||
Metric string `json:"metric" yaml:"metric" hcl:"metric"`
|
||||
From string `json:"from" yaml:"from" hcl:"from"`
|
||||
Metric string `json:"metric" yaml:"metric" hcl:"metric"`
|
||||
From string `json:"from" yaml:"from" hcl:"from"`
|
||||
TargetDatasourceUID *string `json:"targetDatasourceUid,omitempty" yaml:"targetDatasourceUid,omitempty" hcl:"target_datasource_uid,optional"`
|
||||
}
|
||||
|
@ -1010,6 +1010,8 @@ type Record struct {
|
||||
Metric string
|
||||
// From contains a query RefID, indicating which expression node is the output of the recording rule.
|
||||
From string
|
||||
// TargetDatasourceUID is the data source to write the result of the recording rule.
|
||||
TargetDatasourceUID string
|
||||
}
|
||||
|
||||
func (r *Record) Fingerprint() data.Fingerprint {
|
||||
@ -1024,6 +1026,7 @@ func (r *Record) Fingerprint() data.Fingerprint {
|
||||
|
||||
writeString(r.Metric)
|
||||
writeString(r.From)
|
||||
writeString(r.TargetDatasourceUID)
|
||||
return data.Fingerprint(h.Sum64())
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ func (r *recordingRule) tryEvaluation(ctx context.Context, ev *Evaluation, logge
|
||||
}
|
||||
|
||||
writeStart := r.clock.Now()
|
||||
err = r.writer.Write(ctx, ev.rule.Record.Metric, ev.scheduledAt, frames, ev.rule.OrgID, ev.rule.Labels)
|
||||
err = r.writer.WriteDatasource(ctx, ev.rule.Record.TargetDatasourceUID, ev.rule.Record.Metric, ev.scheduledAt, frames, ev.rule.OrgID, ev.rule.Labels)
|
||||
writeDur := r.clock.Now().Sub(writeStart)
|
||||
|
||||
if err != nil {
|
||||
|
@ -50,6 +50,7 @@ type RulesStore interface {
|
||||
|
||||
type RecordingWriter interface {
|
||||
Write(ctx context.Context, name string, t time.Time, frames data.Frames, orgID int64, extraLabels map[string]string) error
|
||||
WriteDatasource(ctx context.Context, dsUID string, name string, t time.Time, frames data.Frames, orgID int64, extraLabels map[string]string) error
|
||||
}
|
||||
|
||||
// AlertRuleStopReasonProvider is an interface for determining the reason why an alert rule was stopped.
|
||||
|
@ -2,6 +2,7 @@ package writer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana-plugin-sdk-go/data"
|
||||
@ -18,3 +19,15 @@ func (w FakeWriter) Write(ctx context.Context, name string, t time.Time, frames
|
||||
|
||||
return w.WriteFunc(ctx, name, t, frames, orgID, extraLabels)
|
||||
}
|
||||
|
||||
func (w FakeWriter) WriteDatasource(ctx context.Context, dsUID string, name string, t time.Time, frames data.Frames, orgID int64, extraLabels map[string]string) error {
|
||||
if w.WriteFunc == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if dsUID != "" {
|
||||
return errors.New("expected empty data source uid")
|
||||
}
|
||||
|
||||
return w.WriteFunc(ctx, name, t, frames, orgID, extraLabels)
|
||||
}
|
||||
|
@ -12,3 +12,7 @@ type NoopWriter struct{}
|
||||
func (w NoopWriter) Write(ctx context.Context, name string, t time.Time, frames data.Frames, orgID int64, extraLabels map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w NoopWriter) WriteDatasource(ctx context.Context, dsUID string, name string, t time.Time, frames data.Frames, orgID int64, extraLabels map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -192,6 +192,18 @@ func createAuthOpts(username, password string) *httpclient.BasicAuthOptions {
|
||||
}
|
||||
}
|
||||
|
||||
// Write writes the given frames to the Prometheus remote write endpoint.
|
||||
func (w PrometheusWriter) WriteDatasource(ctx context.Context, dsUID string, name string, t time.Time, frames data.Frames, orgID int64, extraLabels map[string]string) error {
|
||||
l := w.logger.FromContext(ctx)
|
||||
|
||||
if dsUID != "" {
|
||||
l.Error("Writing to specific data sources is not enabled", "org_id", orgID, "datasource_uid", dsUID)
|
||||
return errors.New("writing to specific data sources is not enabled")
|
||||
}
|
||||
|
||||
return w.Write(ctx, name, t, frames, orgID, extraLabels)
|
||||
}
|
||||
|
||||
// Write writes the given frames to the Prometheus remote write endpoint.
|
||||
func (w PrometheusWriter) Write(ctx context.Context, name string, t time.Time, frames data.Frames, orgID int64, extraLabels map[string]string) error {
|
||||
l := w.logger.FromContext(ctx)
|
||||
|
Reference in New Issue
Block a user