mirror of
https://github.com/prometheus/alertmanager
synced 2024-12-26 16:12:20 +00:00
Implement deterministic alert group order, cleanup
This commit is contained in:
parent
dc656a44ea
commit
ede4b63a91
4
api.go
4
api.go
@ -38,7 +38,7 @@ type API struct {
|
||||
config string
|
||||
uptime time.Time
|
||||
|
||||
groups func() []*UIGroups
|
||||
groups func() AlertOverview
|
||||
|
||||
// context is an indirection for testing.
|
||||
context func(r *http.Request) context.Context
|
||||
@ -46,7 +46,7 @@ type API struct {
|
||||
}
|
||||
|
||||
// NewAPI returns a new API.
|
||||
func NewAPI(alerts provider.Alerts, silences provider.Silences, gf func() []*UIGroups) *API {
|
||||
func NewAPI(alerts provider.Alerts, silences provider.Silences, gf func() AlertOverview) *API {
|
||||
return &API{
|
||||
context: route.Context,
|
||||
alerts: alerts,
|
||||
|
60
dispatch.go
60
dispatch.go
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -59,29 +60,40 @@ func (d *Dispatcher) Run() {
|
||||
close(d.done)
|
||||
}
|
||||
|
||||
// UIGroup is the representation of a group of alerts as provided by
|
||||
// the API.
|
||||
type UIGroup struct {
|
||||
// AlertBlock contains a list of alerts associated with a set of
|
||||
// routing options.
|
||||
type AlertBlock struct {
|
||||
RouteOpts *RouteOpts `json:"routeOpts"`
|
||||
Alerts []*UIAlert `json:"alerts"`
|
||||
Alerts []*APIAlert `json:"alerts"`
|
||||
}
|
||||
|
||||
type UIGroups struct {
|
||||
Labels model.LabelSet `json:"labels"`
|
||||
Groups []*UIGroup `json:"groups"`
|
||||
}
|
||||
|
||||
type UIAlert struct {
|
||||
// APIAlert is the API representation of an alert, which is a regular alert
|
||||
// annotated with silencing and inhibition info.
|
||||
type APIAlert struct {
|
||||
*model.Alert
|
||||
|
||||
Inhibited bool `json:"inhibited"`
|
||||
Silenced uint64 `json:"silenced,omitempty"`
|
||||
}
|
||||
|
||||
func (d *Dispatcher) Groups() []*UIGroups {
|
||||
var groups []*UIGroups
|
||||
// AlertGroup is a list of alert blocks grouped by the same label set.
|
||||
type AlertGroup struct {
|
||||
Labels model.LabelSet `json:"labels"`
|
||||
Blocks []*AlertBlock `json:"blocks"`
|
||||
}
|
||||
|
||||
seen := map[model.Fingerprint]*UIGroups{}
|
||||
// AlertOverview is a representation of all active alerts in the system.
|
||||
type AlertOverview []*AlertGroup
|
||||
|
||||
func (ao AlertOverview) Swap(i, j int) { ao[i], ao[j] = ao[j], ao[i] }
|
||||
func (ao AlertOverview) Less(i, j int) bool { return ao[i].Labels.Before(ao[j].Labels) }
|
||||
func (ao AlertOverview) Len() int { return len(ao) }
|
||||
|
||||
// Groups populates an AlertOverview from the dispatcher's internal state.
|
||||
func (d *Dispatcher) Groups() AlertOverview {
|
||||
var overview AlertOverview
|
||||
|
||||
seen := map[model.Fingerprint]*AlertGroup{}
|
||||
|
||||
for route, ags := range d.aggrGroups {
|
||||
for _, ag := range ags {
|
||||
@ -90,39 +102,41 @@ func (d *Dispatcher) Groups() []*UIGroups {
|
||||
alerts = append(alerts, a)
|
||||
}
|
||||
|
||||
uig, ok := seen[ag.labels.Fingerprint()]
|
||||
alertGroup, ok := seen[ag.labels.Fingerprint()]
|
||||
if !ok {
|
||||
uig = &UIGroups{Labels: ag.labels}
|
||||
alertGroup = &AlertGroup{Labels: ag.labels}
|
||||
|
||||
seen[ag.labels.Fingerprint()] = uig
|
||||
groups = append(groups, uig)
|
||||
seen[ag.labels.Fingerprint()] = alertGroup
|
||||
overview = append(overview, alertGroup)
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
|
||||
var uiAlerts []*UIAlert
|
||||
var apiAlerts []*APIAlert
|
||||
for _, a := range types.Alerts(alerts...) {
|
||||
if a.EndsAt.Before(now) {
|
||||
if !a.EndsAt.IsZero() && a.EndsAt.Before(now) {
|
||||
continue
|
||||
}
|
||||
|
||||
sid, _ := d.marker.Silenced(a.Fingerprint())
|
||||
|
||||
uiAlerts = append(uiAlerts, &UIAlert{
|
||||
apiAlerts = append(apiAlerts, &APIAlert{
|
||||
Alert: a,
|
||||
Inhibited: d.marker.Inhibited(a.Fingerprint()),
|
||||
Silenced: sid,
|
||||
})
|
||||
}
|
||||
|
||||
uig.Groups = append(uig.Groups, &UIGroup{
|
||||
alertGroup.Blocks = append(alertGroup.Blocks, &AlertBlock{
|
||||
RouteOpts: &route.RouteOpts,
|
||||
Alerts: uiAlerts,
|
||||
Alerts: apiAlerts,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return groups
|
||||
sort.Sort(overview)
|
||||
|
||||
return overview
|
||||
}
|
||||
|
||||
func (d *Dispatcher) run(it provider.AlertIterator) {
|
||||
|
2
main.go
2
main.go
@ -69,7 +69,7 @@ func main() {
|
||||
)
|
||||
defer disp.Stop()
|
||||
|
||||
api := NewAPI(alerts, silences, func() []*UIGroups {
|
||||
api := NewAPI(alerts, silences, func() AlertOverview {
|
||||
return disp.Groups()
|
||||
})
|
||||
|
||||
|
@ -174,9 +174,9 @@ angular.module('am.controllers').controller('AlertsCtrl',
|
||||
|
||||
$scope.notEmpty = function(group) {
|
||||
var l = 0;
|
||||
angular.forEach(group.groups, function(g) {
|
||||
if ($scope.receiver.indexOf(g.routeOpts.receiver) >= 0) {
|
||||
l += g.alerts.length;
|
||||
angular.forEach(group.blocks, function(blk) {
|
||||
if ($scope.receivers.indexOf(blk.routeOpts.receiver) >= 0) {
|
||||
l += blk.alerts.length || 0;
|
||||
}
|
||||
});
|
||||
|
||||
@ -190,9 +190,9 @@ angular.module('am.controllers').controller('AlertsCtrl',
|
||||
|
||||
$scope.allReceivers = [];
|
||||
angular.forEach($scope.groups, function(group) {
|
||||
angular.forEach(group.groups, function(g) {
|
||||
if ($scope.allReceivers.indexOf(g.routeOpts.receiver) < 0) {
|
||||
$scope.allReceivers.push(g.routeOpts.receiver);
|
||||
angular.forEach(group.blocks, function(blk) {
|
||||
if ($scope.allReceivers.indexOf(blk.routeOpts.receiver) < 0) {
|
||||
$scope.allReceivers.push(blk.routeOpts.receiver);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
@ -13,9 +13,9 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="g in group.groups">
|
||||
<div ng-show="receivers.indexOf(g.routeOpts.receiver) >= 0" ng-show"g.alerts">
|
||||
<div ng-repeat="a in g.alerts">
|
||||
<div ng-repeat="blk in group.blocks">
|
||||
<div ng-show="receivers.indexOf(blk.routeOpts.receiver) >= 0" ng-show"blk.alerts">
|
||||
<div ng-repeat="a in blk.alerts">
|
||||
<alert class="list-item" alert="a" group="group.labels"></alert>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user