grafana/pkg/registry/registry.go
Sofia Papagiannaki 43f580c299
AlertingNG: manage and evaluate alert definitions via the API (#28377)
* 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>
2020-11-12 15:11:30 +02:00

127 lines
3.2 KiB
Go

package registry
import (
"context"
"reflect"
"sort"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
)
type Descriptor struct {
Name string
Instance Service
InitPriority Priority
}
var services []*Descriptor
func RegisterServiceWithPriority(instance Service, priority Priority) {
services = append(services, &Descriptor{
Name: reflect.TypeOf(instance).Elem().Name(),
Instance: instance,
InitPriority: priority,
})
}
func RegisterService(instance Service) {
services = append(services, &Descriptor{
Name: reflect.TypeOf(instance).Elem().Name(),
Instance: instance,
InitPriority: Medium,
})
}
func Register(descriptor *Descriptor) {
services = append(services, descriptor)
}
func GetServices() []*Descriptor {
slice := getServicesWithOverrides()
sort.Slice(slice, func(i, j int) bool {
return slice[i].InitPriority > slice[j].InitPriority
})
return slice
}
type OverrideServiceFunc func(descriptor Descriptor) (*Descriptor, bool)
var overrides []OverrideServiceFunc
func RegisterOverride(fn OverrideServiceFunc) {
overrides = append(overrides, fn)
}
func getServicesWithOverrides() []*Descriptor {
slice := []*Descriptor{}
for _, s := range services {
var descriptor *Descriptor
for _, fn := range overrides {
if newDescriptor, override := fn(*s); override {
descriptor = newDescriptor
break
}
}
if descriptor != nil {
slice = append(slice, descriptor)
} else {
slice = append(slice, s)
}
}
return slice
}
// Service interface is the lowest common shape that services
// are expected to fulfill to be started within Grafana.
type Service interface {
// Init is called by Grafana main process which gives the service
// the possibility do some initial work before its started. Things
// like adding routes, bus handlers should be done in the Init function
Init() error
}
// CanBeDisabled allows the services to decide if it should
// be started or not by itself. This is useful for services
// that might not always be started, ex alerting.
// This will be called after `Init()`.
type CanBeDisabled interface {
// IsDisabled should return a bool saying if it can be started or not.
IsDisabled() bool
}
// BackgroundService should be implemented for services that have
// long running tasks in the background.
type BackgroundService interface {
// Run starts the background process of the service after `Init` have been called
// on all services. The `context.Context` passed into the function should be used
// to subscribe to ctx.Done() so the service can be notified when Grafana shuts down.
Run(ctx context.Context) error
}
// DatabaseMigrator allows the caller to add migrations to
// the migrator passed as argument
type DatabaseMigrator interface {
// AddMigrations allows the service to add migrations to
// the database migrator.
AddMigration(mg *migrator.Migrator)
}
// IsDisabled returns whether a service is disabled.
func IsDisabled(srv Service) bool {
canBeDisabled, ok := srv.(CanBeDisabled)
return ok && canBeDisabled.IsDisabled()
}
type Priority int
const (
High Priority = 100
MediumHigh Priority = 75
Medium Priority = 50
Low Priority = 0
)