mirror of
https://github.com/prometheus/alertmanager
synced 2025-01-13 17:43:26 +00:00
Implement endpoint for UI routing tree representation
This commit is contained in:
parent
e151f029b7
commit
524d08d567
35
api.go
35
api.go
@ -32,15 +32,19 @@ import (
|
||||
type API struct {
|
||||
alerts provider.Alerts
|
||||
silences provider.Silences
|
||||
|
||||
route func() *UIRoute
|
||||
|
||||
// context is an indirection for testing.
|
||||
context func(r *http.Request) context.Context
|
||||
}
|
||||
|
||||
func RegisterAPI(r *route.Router, alerts provider.Alerts, silences provider.Silences) *API {
|
||||
func RegisterAPI(r *route.Router, alerts provider.Alerts, silences provider.Silences, rf func() *UIRoute) *API {
|
||||
api := &API{
|
||||
context: route.Context,
|
||||
alerts: alerts,
|
||||
silences: silences,
|
||||
route: rf,
|
||||
}
|
||||
|
||||
// Register legacy forwarder for alert pushing.
|
||||
@ -49,6 +53,8 @@ func RegisterAPI(r *route.Router, alerts provider.Alerts, silences provider.Sile
|
||||
// Register actual API.
|
||||
r = r.WithPrefix("/v1")
|
||||
|
||||
r.Get("/routes", api.routes)
|
||||
|
||||
r.Get("/alerts", api.listAlerts)
|
||||
r.Post("/alerts", api.addAlerts)
|
||||
|
||||
@ -80,6 +86,33 @@ func (e *apiError) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.typ, e.err)
|
||||
}
|
||||
|
||||
func pruneUIRoute(r *UIRoute) {
|
||||
for _, sr := range r.Routes {
|
||||
pruneUIRoute(sr)
|
||||
}
|
||||
|
||||
var nr []*UIRoute
|
||||
|
||||
for _, sr := range r.Routes {
|
||||
if len(sr.Groups) == 0 && len(sr.Routes) == 0 {
|
||||
continue
|
||||
}
|
||||
nr = append(nr, sr)
|
||||
}
|
||||
|
||||
r.Routes = nr
|
||||
}
|
||||
|
||||
func (api *API) routes(w http.ResponseWriter, req *http.Request) {
|
||||
r := api.route()
|
||||
|
||||
if req.FormValue("pruneEmpty") == "true" {
|
||||
pruneUIRoute(r)
|
||||
}
|
||||
|
||||
respond(w, r)
|
||||
}
|
||||
|
||||
func (api *API) listAlerts(w http.ResponseWriter, r *http.Request) {
|
||||
alerts := api.alerts.GetPending()
|
||||
defer alerts.Close()
|
||||
|
35
dispatch.go
35
dispatch.go
@ -54,6 +54,41 @@ func (d *Dispatcher) Run() {
|
||||
close(d.done)
|
||||
}
|
||||
|
||||
type UIRoute struct {
|
||||
RouteOpts *RouteOpts
|
||||
Matchers types.Matchers
|
||||
Groups []*UIGroup
|
||||
Routes []*UIRoute
|
||||
}
|
||||
|
||||
type UIGroup struct {
|
||||
Labels model.LabelSet
|
||||
Alerts model.Alerts
|
||||
}
|
||||
|
||||
func (d *Dispatcher) Populate(r *UIRoute) {
|
||||
for _, sr := range r.Routes {
|
||||
d.Populate(sr)
|
||||
}
|
||||
|
||||
groups, ok := d.aggrGroups[r.RouteOpts]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
for _, ag := range groups {
|
||||
var as []*types.Alert
|
||||
for _, a := range ag.alerts {
|
||||
as = append(as, a)
|
||||
}
|
||||
g := &UIGroup{
|
||||
Labels: ag.labels,
|
||||
Alerts: types.Alerts(as...),
|
||||
}
|
||||
r.Groups = append(r.Groups, g)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Dispatcher) run(it provider.AlertIterator) {
|
||||
cleanup := time.NewTicker(30 * time.Second)
|
||||
defer cleanup.Stop()
|
||||
|
7
main.go
7
main.go
@ -128,7 +128,12 @@ func main() {
|
||||
router := route.New()
|
||||
|
||||
RegisterWeb(router)
|
||||
RegisterAPI(router.WithPrefix("/api"), alerts, silences)
|
||||
RegisterAPI(router.WithPrefix("/api"), alerts, silences, func() *UIRoute {
|
||||
uir := disp.route.UIRoute()
|
||||
disp.Populate(uir)
|
||||
|
||||
return uir
|
||||
})
|
||||
|
||||
go http.ListenAndServe(*listenAddress, router)
|
||||
|
||||
|
14
route.go
14
route.go
@ -115,6 +115,20 @@ func NewRoutes(croutes []*config.Route, parent *Route) []*Route {
|
||||
return res
|
||||
}
|
||||
|
||||
func (r *Route) UIRoute() *UIRoute {
|
||||
var subs []*UIRoute
|
||||
for _, sr := range r.Routes {
|
||||
subs = append(subs, sr.UIRoute())
|
||||
}
|
||||
|
||||
uir := &UIRoute{
|
||||
RouteOpts: &r.RouteOpts,
|
||||
Matchers: r.Matchers,
|
||||
Routes: subs,
|
||||
}
|
||||
return uir
|
||||
}
|
||||
|
||||
// Match does a depth-first left-to-right search through the route tree
|
||||
// and returns the flattened configuration for the reached node.
|
||||
func (r *Route) Match(lset model.LabelSet) []*RouteOpts {
|
||||
|
Loading…
Reference in New Issue
Block a user