mirror of
https://github.com/grafana/grafana.git
synced 2025-02-20 11:48:34 -06:00
* Alerting NG: prototype v2 (WIP) * Separate eval package * Modify eval alert definition endpoint * Disable migration if ngalert is not enabled * Remove premature test * Fix lint issues * Delete obsolete struct * Apply suggestions from code review * Update pkg/services/ngalert/ngalert.go Co-authored-by: Kyle Brandt <kyle@grafana.com> * Add API endpoint for listing alert definitions * Introduce index for alert_definition table * make ds object for expression to avoid panic * wrap error * Update pkg/services/ngalert/eval/eval.go * Swith to backend.DataQuery * Export TransformWrapper callback * Fix lint issues * Update pkg/services/ngalert/ngalert.go Co-authored-by: Kyle Brandt <kyle@grafana.com> * Validate alert definitions before storing them * Introduce AlertQuery * Add test * Add QueryType in AlertQuery * Accept only float64 (seconds) durations * Apply suggestions from code review * Get rid of bus * Do not export symbols * Fix failing test * Fix failure due to service initialization order Introduce MediumHigh service priority and assign it to backendplugin service * Fix test * Apply suggestions from code review * Fix renamed reference Co-authored-by: Kyle Brandt <kyle@grafana.com>
92 lines
2.9 KiB
Go
92 lines
2.9 KiB
Go
package ngalert
|
|
|
|
import (
|
|
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
|
|
|
"github.com/grafana/grafana/pkg/api/routing"
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
"github.com/grafana/grafana/pkg/registry"
|
|
"github.com/grafana/grafana/pkg/services/datasources"
|
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
|
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
)
|
|
|
|
// AlertNG is the service for evaluating the condition of an alert definition.
|
|
type AlertNG struct {
|
|
Cfg *setting.Cfg `inject:""`
|
|
DatasourceCache datasources.CacheService `inject:""`
|
|
RouteRegister routing.RouteRegister `inject:""`
|
|
SQLStore *sqlstore.SQLStore `inject:""`
|
|
log log.Logger
|
|
}
|
|
|
|
func init() {
|
|
registry.RegisterService(&AlertNG{})
|
|
}
|
|
|
|
// Init initializes the AlertingService.
|
|
func (ng *AlertNG) Init() error {
|
|
ng.log = log.New("ngalert")
|
|
|
|
ng.registerAPIEndpoints()
|
|
|
|
return nil
|
|
}
|
|
|
|
// IsDisabled returns true if the alerting service is disable for this instance.
|
|
func (ng *AlertNG) IsDisabled() bool {
|
|
if ng.Cfg == nil {
|
|
return false
|
|
}
|
|
// Check also about expressions?
|
|
return !ng.Cfg.IsNgAlertEnabled()
|
|
}
|
|
|
|
// AddMigration defines database migrations.
|
|
// If Alerting NG is not enabled does nothing.
|
|
func (ng *AlertNG) AddMigration(mg *migrator.Migrator) {
|
|
if ng.IsDisabled() {
|
|
return
|
|
}
|
|
|
|
alertDefinition := migrator.Table{
|
|
Name: "alert_definition",
|
|
Columns: []*migrator.Column{
|
|
{Name: "id", Type: migrator.DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
|
|
{Name: "org_id", Type: migrator.DB_BigInt, Nullable: false},
|
|
{Name: "name", Type: migrator.DB_NVarchar, Length: 255, Nullable: false},
|
|
{Name: "condition", Type: migrator.DB_NVarchar, Length: 255, Nullable: false},
|
|
{Name: "data", Type: migrator.DB_Text, Nullable: false},
|
|
},
|
|
Indices: []*migrator.Index{
|
|
{Cols: []string{"org_id"}, Type: migrator.IndexType},
|
|
},
|
|
}
|
|
// create table
|
|
mg.AddMigration("create alert_definition table", migrator.NewAddTableMigration(alertDefinition))
|
|
|
|
// create indices
|
|
mg.AddMigration("add index alert_definition org_id", migrator.NewAddIndexMigration(alertDefinition, alertDefinition.Indices[0]))
|
|
}
|
|
|
|
// LoadAlertCondition returns a Condition object for the given alertDefinitionID.
|
|
func (ng *AlertNG) LoadAlertCondition(alertDefinitionID int64, signedInUser *models.SignedInUser, skipCache bool) (*eval.Condition, error) {
|
|
getAlertDefinitionByIDQuery := getAlertDefinitionByIDQuery{ID: alertDefinitionID}
|
|
if err := ng.getAlertDefinitionByID(&getAlertDefinitionByIDQuery); err != nil {
|
|
return nil, err
|
|
}
|
|
alertDefinition := getAlertDefinitionByIDQuery.Result
|
|
|
|
err := ng.validateAlertDefinition(alertDefinition, signedInUser, skipCache)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &eval.Condition{
|
|
RefID: alertDefinition.Condition,
|
|
QueriesAndExpressions: alertDefinition.Data,
|
|
}, nil
|
|
}
|