Sorting alerts by group name in /alerts (#5448)

* Working group name

Signed-off-by: Pritam Bhudia <pritam.bhudia@baesystems.com>

* Working categorised by group name

Signed-off-by: Pritam Bhudia <pritam.bhudia@baesystems.com>

* Changed group sorting in web

Signed-off-by: Pritam Bhudia <pritam.bhudia@baesystems.com>

* Fixed group sorting and comments

Signed-off-by: Pritam Bhudia <pritam.bhudia@baesystems.com>

* Fixed group sorting and comments with gofmt

Signed-off-by: Pritam Bhudia <pritam.bhudia@baesystems.com>

* Added file and group name

Signed-off-by: Pritam Bhudia <pritam.bhudia@baesystems.com>

* reverted back to full path to yml file

Signed-off-by: Pritam Bhudia <pritam.bhudia@baesystems.com>
This commit is contained in:
pbhudiaBAE 2019-05-14 21:14:27 +00:00 committed by Julius Volz
parent 20eb23e0ca
commit 43953b105b
4 changed files with 104 additions and 79 deletions

View File

@ -361,6 +361,38 @@ func (g *Group) hash() uint64 {
return l.Hash()
}
// AlertingRules returns the list of the group's alerting rules.
func (g *Group) AlertingRules() []*AlertingRule {
g.mtx.Lock()
defer g.mtx.Unlock()
var alerts []*AlertingRule
for _, rule := range g.rules {
if alertingRule, ok := rule.(*AlertingRule); ok {
alerts = append(alerts, alertingRule)
}
}
sort.Slice(alerts, func(i, j int) bool {
return alerts[i].State() > alerts[j].State() ||
(alerts[i].State() == alerts[j].State() &&
alerts[i].Name() < alerts[j].Name())
})
return alerts
}
// HasAlertingRules returns true if the group contains at least one AlertingRule.
func (g *Group) HasAlertingRules() bool {
g.mtx.Lock()
defer g.mtx.Unlock()
for _, rule := range g.rules {
if _, ok := rule.(*AlertingRule); ok {
return true
}
}
return false
}
// GetEvaluationDuration returns the time in seconds it took to evaluate the rule group.
func (g *Group) GetEvaluationDuration() time.Duration {
g.mtx.Lock()
@ -871,7 +903,6 @@ func (m *Manager) RuleGroups() []*Group {
rgs = append(rgs, g)
}
// Sort rule groups by file, then by name.
sort.Slice(rgs, func(i, j int) bool {
if rgs[i].file != rgs[j].file {
return rgs[i].file < rgs[j].file
@ -906,6 +937,7 @@ func (m *Manager) AlertingRules() []*AlertingRule {
alerts = append(alerts, alertingRule)
}
}
return alerts
}

View File

@ -633,9 +633,9 @@ var Assets = func() http.FileSystem {
"/templates/alerts.html": &vfsgen۰CompressedFileInfo{
name: "alerts.html",
modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC),
uncompressedSize: 2698,
uncompressedSize: 3065,
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x56\xcd\x8e\xdb\x36\x10\xbe\xef\x53\x0c\x94\x1c\x5a\xa0\xb2\xb0\xd8\xe4\x50\x9b\x56\xb1\xc8\xa5\x87\x24\x28\xb2\xe9\x5e\x17\x14\x39\xb6\x18\x73\x49\x81\xa4\xbd\x76\x59\xbd\x7b\x41\x52\xf2\xca\xb2\xd4\xa4\x40\x61\x40\x20\x87\xc3\x6f\xbe\xf9\xe1\x8c\xbd\xe7\xb8\x11\x0a\x21\xab\x91\xf2\xac\x6d\x6f\x00\x88\x14\x6a\x07\xee\xd4\xe0\x3a\x73\x78\x74\x05\xb3\x36\x03\x83\x72\x9d\x59\x77\x92\x68\x6b\x44\x97\x41\x6d\x70\xb3\xce\xbc\x87\x86\xba\xfa\x0f\x83\x1b\x71\x84\xb6\x2d\xac\xa3\x4e\xb0\x70\xa7\xa0\x12\x8d\xb3\x0b\x66\xed\x6f\x87\xb5\xf7\x50\xed\x85\xe4\x8f\x68\xac\xd0\x0a\xda\x36\x2b\x83\x31\xcb\x8c\x68\x1c\x58\xc3\xe6\xc1\xbe\x9d\xb1\xbe\xcd\x41\x91\x22\x01\x95\x37\xde\xa3\xe2\x6d\x7b\x73\xf3\xea\x1b\xd3\xca\xa1\x72\xc1\x3d\xc2\xc5\x01\x98\xa4\xd6\xae\xa3\x98\x0a\x85\x26\xdf\xc8\xbd\xe0\x89\x4f\x7d\x5b\xde\x47\x5b\xa4\xa8\x6f\xa3\x64\x70\xc3\xd6\xfa\x25\xa7\x4a\xe9\xc0\x4b\x2b\x1b\xaf\x00\x00\x11\xbd\xc6\x56\x9e\x9a\x5a\x30\xad\xe0\xbc\xca\xf7\x8a\xd5\xc8\x76\xc8\x03\x4d\xd1\x5d\x01\x20\xd5\xde\x39\xad\xba\x48\xa7\x4d\x36\x6b\x09\x9c\x70\x12\xd3\x01\x5c\x50\x78\x18\x49\x48\x91\xb0\x22\xf9\x82\x8b\x43\x5c\x38\x5a\x49\xec\xd1\xd3\x26\x7e\xf3\x4a\x1b\x8e\x06\x79\xb7\x65\x5a\x4a\xda\x58\xe4\x9d\x6f\xc4\x55\x9a\x9f\xd2\xda\xfb\xb7\x31\x0f\x0f\x8e\x3a\xfc\xaa\xbf\xe8\x97\x0f\x01\x0f\x96\x6b\x58\xdc\x4f\x1c\xc4\x72\x0a\xd7\x0c\x55\x5b\xec\x74\x84\xda\x7e\xd9\x4b\xec\x0f\x13\x2a\x73\xe2\x80\x29\xee\x09\x6d\x20\x38\x2b\x12\x67\x7a\x07\x22\x0d\x88\xdf\xdc\x7b\xa1\x38\x1e\x61\x9a\xdb\x22\x0a\xda\x36\x29\x3f\x85\x32\x47\x93\x9d\x93\x00\xc4\xf1\xf2\x35\x7d\x31\x5f\xac\xc6\x83\xd1\x2a\xe7\xfa\x45\xa5\x94\x01\xa9\x4a\xef\x17\x9f\xe9\x33\xb6\x2d\x29\xaa\x12\x7e\xf2\x5e\xa2\x82\x0b\xe6\xc1\x48\xdc\xfe\x4c\x0a\xc7\x7b\x13\xa4\x70\xa6\x9c\xf1\xe0\x89\xa3\xa3\x42\xda\x11\x9f\xf3\x26\x55\xdf\x70\x0f\x40\x1a\x83\x10\x1f\xe2\x3a\xe3\xc2\x36\x92\x9e\x96\x95\xd4\x6c\xb7\x82\x86\x72\x2e\xd4\x76\xf9\xeb\xe2\x7d\x73\x5c\xc1\x46\x2b\x97\x5b\xf1\x17\x2e\x6f\xef\xc2\x9e\x69\xa9\xcd\xf2\xcd\xdd\xdd\xdd\x0a\x5e\xb4\xe1\x79\x65\x90\xee\x96\xf1\x9b\x53\x29\x57\x50\x51\xb6\xdb\x1a\xbd\x57\x3c\xef\x94\x37\xef\xc3\x6f\x05\xa9\x4a\x96\xb7\xcd\x11\xac\x96\x82\xc3\x1b\xc6\x58\x2f\xce\x0d\xe5\x62\x6f\x97\xef\x9a\xe3\x2a\x83\x92\x30\xcd\x31\xc4\xeb\xf7\xaf\x9f\x3e\x3e\x28\xd1\x34\xe8\x06\x0f\x3b\x44\x30\x6a\x90\xa2\x31\x78\xe1\x6c\x31\xf2\xd6\x7b\xb1\x19\xc7\x78\xa8\xff\xa3\x45\x5d\xeb\x03\x9a\x6e\x6d\x9f\xbb\x52\x40\x89\xcf\xa8\x9c\x7d\x8a\xf2\x6c\x14\xe5\xd7\x4c\x8d\x4e\xc2\x59\x5d\x7e\xa4\x15\x4a\x4b\x0a\x57\x4f\x9d\xc6\x9a\x9b\x3b\x4c\xb5\x0d\x0f\x42\xb1\x59\x9d\x47\x2a\xf7\x13\x87\xc3\x5a\xea\x23\x94\xde\xd6\x7c\x90\xa2\x2f\xd7\x36\xf8\x58\x34\xc0\x92\xc1\xb9\x5f\xe0\xed\x21\xb0\x88\xef\x31\xb9\xbb\xf8\x44\x9b\x11\x76\x07\x67\x1b\xaa\xfa\x78\x55\x94\x6f\x11\xe2\x37\x6f\x8c\x78\xa6\xe6\x94\x95\xde\x27\xd4\xb6\x0d\x6d\x3e\x21\xb7\x6d\x46\x8a\x70\x73\x8a\x4a\x6a\xe2\x23\x33\xc5\x35\xed\xf8\x7e\x87\xe6\x2f\x5b\x43\xf7\xfe\xe1\x6f\x18\x76\x87\xd4\x1a\xda\x16\xc2\x80\xc1\x27\xa1\xb8\x60\xd4\x69\x03\x61\xde\xe5\xfb\xa6\x41\xc3\xa8\xc5\x40\xbb\xef\x1f\x1d\xd3\x39\x0a\xde\xf7\x3d\xcb\x2d\xfe\xfc\xfa\x21\xe8\xcf\x2a\x3e\x26\xe7\xaf\x35\xa6\xd2\x0b\x62\x03\x8b\xfb\xd7\xee\x3e\x91\x83\x50\xab\xa3\x86\xa0\xb4\xc2\xec\xb2\xd5\x4c\x8c\xad\x01\x42\x1d\xba\x43\xf0\x70\x9d\xbd\xcb\xca\xfb\xe1\x34\xf9\x7e\x11\xfe\x1f\x04\xf8\x05\x81\xab\x82\x20\x5c\xfe\xa7\x82\xfd\xf7\x88\xf5\x98\x6e\x50\x97\xa4\xe0\xee\xda\x44\xd0\x0a\x49\xeb\x2b\x96\x14\x7c\xf2\xe5\x4c\x95\x6b\x6c\x68\x57\xb4\x7f\x2c\xed\xd7\x78\xd7\x32\x52\xc4\xce\x75\xd9\x30\x2f\x95\xa6\x07\x91\xf7\x28\x2d\x0e\xe7\xea\xec\xfc\x01\xf8\xac\xd3\xd3\x11\x6a\x0b\x26\x0c\x6e\x48\x7f\xab\xf8\xf7\x8d\x9c\xa9\x90\xe2\xfc\x2f\xe2\x4c\xba\x6b\xf6\xbd\xda\x3f\x01\x00\x00\xff\xff\x90\x89\x38\x20\x8a\x0a\x00\x00"),
compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x56\xd1\x6f\xdb\xb6\x13\x7e\xcf\x5f\x71\x50\xfb\xf0\xfb\x01\x93\x85\x2c\xed\xc3\x6c\x5a\x43\x50\x60\xdb\x43\x5b\x0c\x4d\x97\xd7\x80\x22\xcf\x16\x1b\x86\x14\x48\xda\xb1\xc7\xe9\x7f\x1f\x48\x4a\x8e\x2c\xcb\x6e\x0a\x0c\x06\x0c\xf1\x74\x77\xfc\xbe\xe3\xc7\x3b\x79\xcf\x71\x25\x14\x42\x56\x23\xe5\x59\xdb\x5e\x01\x10\x29\xd4\x23\xb8\x7d\x83\xcb\xcc\xe1\xce\x15\xcc\xda\x0c\x0c\xca\x65\x66\xdd\x5e\xa2\xad\x11\x5d\x06\xb5\xc1\xd5\x32\xf3\x1e\x1a\xea\xea\x3f\x0d\xae\xc4\x0e\xda\xb6\xb0\x8e\x3a\xc1\x42\x4c\x41\x25\x1a\x67\x67\xcc\xda\x5f\xb7\x4b\xef\xa1\xda\x08\xc9\xef\xd1\x58\xa1\x15\xb4\x6d\x56\x86\xcd\x2c\x33\xa2\x71\x60\x0d\x3b\x9f\xec\xdb\x21\xd7\xb7\x73\xa9\x48\x91\x12\x95\x57\xde\xa3\xe2\x6d\x7b\x75\xf5\xc2\x8d\x69\xe5\x50\xb9\x40\x8f\x70\xb1\x05\x26\xa9\xb5\xcb\x68\xa6\x42\xa1\xc9\x57\x72\x23\x78\xc2\x53\x5f\x97\xb7\x71\x2f\x52\xd4\xd7\xd1\x32\x88\xb0\xb5\x7e\xce\xa9\x52\x3a\xe0\xd2\xca\xc6\x10\x00\x20\xa2\xf7\x58\xcb\x7d\x53\x0b\xa6\x15\x1c\x9e\xf2\x8d\x62\x35\xb2\x47\xe4\x01\xa6\xe8\x42\x00\x48\xb5\x71\x4e\xab\xae\xd2\x69\x91\x9d\xdd\x09\x9c\x70\x12\xd3\x0b\x38\x82\x70\x37\xb2\x90\x22\xe5\x8a\xe0\x0b\x2e\xb6\xf1\xc1\xd1\x4a\x62\x9f\x3d\x2d\xe2\x7f\x5e\x69\xc3\xd1\x20\xef\x96\x4c\x4b\x49\x1b\x8b\xbc\xe3\x46\x5c\xa5\xf9\xbe\x07\xed\xfd\xdb\x78\x12\x77\x8e\x3a\xfc\xaa\xbf\xe8\xe7\x0f\x21\x23\xcc\x97\x30\xbb\x9d\x78\x11\x05\x95\x02\x0d\x55\x6b\x84\xd9\xef\x46\x6f\x9a\x17\x3b\x71\xe6\x50\x10\x20\x8e\x43\x94\xd8\x32\x6b\x28\xe7\x42\xad\xe7\xf0\x73\xb3\xcb\x5e\x3c\x42\xa2\xd9\x6f\x42\x62\xdb\x42\x19\x9e\x3f\xd3\x27\x3c\x24\x0b\x7c\x1d\xef\xbd\x49\x31\xcc\x7d\x00\x10\x61\x0a\xb5\xfe\xb2\x91\x68\x07\xa1\x89\x1c\x73\x62\x8b\x49\x00\x89\xd4\xc0\x70\xe4\x4c\x9c\xe9\xab\x19\x2b\x02\xf1\x3f\xf7\x5e\x28\x8e\x3b\x98\x2e\xd3\x2c\x1a\xda\x36\x39\x3f\x84\x3b\x87\xe6\x88\x5e\x57\x86\xf2\x45\x51\x51\x42\xac\xc6\xad\xd1\x2a\xe7\xfa\x59\x25\x15\x01\xa9\xca\x03\x7f\x52\x54\x25\xfc\xcf\x7b\x89\x0a\x8e\x38\x84\xad\xe2\xf2\xff\xc3\xca\x9c\x56\xe7\x94\xcf\x03\x47\x47\x85\xb4\x23\x74\xe4\x38\x4b\x34\x75\x12\x1b\x59\x1b\x83\xfd\x61\x72\x61\x1b\x49\xf7\xf3\x4a\x6a\xf6\xb8\x80\xfe\x6c\x7f\x99\xbd\x6f\x76\x0b\x58\x69\xe5\x72\x2b\xfe\xc6\xf9\xf5\x4d\x58\x33\x2d\xb5\x99\xbf\xb9\xb9\xb9\x59\xc0\xb3\x36\x3c\xaf\x0c\xd2\xc7\x79\xfc\xcf\xa9\x94\x0b\xa8\x28\x7b\x5c\x1b\xbd\x51\x3c\xef\x9c\x57\xef\xc3\x6f\x01\x49\xcc\xf3\xeb\x66\x07\x56\x4b\xc1\xe1\x0d\x63\xac\x37\xe7\x86\x72\xb1\xb1\xf3\x77\xcd\x6e\x91\x41\x49\x98\xe6\x18\x6a\xf8\xc7\xd7\x4f\x1f\xef\x94\x68\x1a\x74\x83\xfe\x13\xaa\x1a\x3d\x48\xd1\x18\x3c\x21\x5d\x4c\xb0\xf6\x5e\xac\xc6\xf5\x3f\x39\xdb\x57\xde\xc3\x5a\x6f\xd1\x74\xcf\xf6\xa9\x13\x0c\x4a\x7c\x42\xe5\xec\x43\xb4\x9f\x08\xe7\xe8\x14\x27\xde\x86\xf7\x75\xf9\x91\x56\x28\x2d\x29\x5c\x7d\xce\x23\xaa\xf4\x92\x43\xba\x15\x70\x27\x14\xbb\xe8\x77\x4f\xe5\xe6\x8c\xc3\x58\x7f\x7d\x05\xd3\x2d\xbd\x5c\xc4\x51\xdb\x18\x9a\x4f\xd4\x39\xca\x2b\x03\xf9\x9f\xe0\xed\x36\x20\x8b\x37\x3c\x95\x63\xf6\x89\x36\x13\xfb\x74\x69\x6d\x43\x55\x5f\xd7\x8a\xf2\x35\x42\xfc\xcf\x1b\x23\x9e\xa8\xd9\x67\xa5\xf7\x29\x73\xdb\x86\x29\x96\xb2\xb7\x6d\x46\x8a\x10\x79\x0e\x52\x9a\x53\x13\xdb\x15\xd3\x34\x62\x5f\x18\x42\x39\x6e\x3c\x5d\x77\x81\x7f\x60\xd8\x7b\x52\xe3\x69\x5b\x08\xb3\x14\x1f\x84\xe2\x82\x51\xa7\x0d\x84\xd1\x9e\x6f\x9a\x06\x0d\xa3\x16\x03\x85\xbe\x3b\x75\xa8\x2f\xc1\xf0\xbe\xef\x8c\x6e\xf6\xd7\xd7\x0f\x21\xe6\xa2\xf3\x7d\x2a\xc8\xb4\xd7\x39\x29\x80\x58\xc1\xec\xf6\x65\xb0\x9d\x39\xa3\xa0\xf9\x51\xa3\x51\x5a\x61\x76\xdc\xce\x26\xa6\xf6\x28\x4b\x1d\x3a\x4f\x60\xbe\xcc\xde\x65\xe5\xed\x70\xa0\xbe\x5e\xc0\xff\x15\x18\x7e\x04\x66\x52\x40\x84\xcb\x1f\x16\xfb\xf7\xab\xd9\xe7\x76\x03\x4d\x93\x82\xbb\xe9\xad\x82\x67\x38\xe0\x5e\xf1\xa4\xe0\x67\x6f\xe0\x39\xb9\xc7\x66\x3a\x49\xe5\xc7\xe4\x32\x9d\x7f\xda\x4e\x8a\xd8\x41\x4f\x1b\xf8\xa9\xf3\xe5\xc1\x39\x8e\xf0\x1e\xa5\xc5\xf1\x97\xc2\x77\x67\x28\xc0\x67\x9d\xae\xad\x50\x6b\x30\xe1\xd3\x04\xd2\xd7\x2b\x7f\x25\x98\x21\x10\x52\x1c\x3e\xda\x0e\x44\xbb\x81\xd5\xbb\xfd\x1b\x00\x00\xff\xff\x71\xca\xa7\x74\xf9\x0b\x00\x00"),
},
"/templates/config.html": &vfsgen۰CompressedFileInfo{
name: "config.html",

View File

@ -12,62 +12,69 @@
</div>
<table class="table table-bordered table-collapsed">
<tbody>
{{$alertStateToRowClass := .AlertStateToRowClass}}
{{range .AlertingRules}}
{{$activeAlerts := .ActiveAlerts}}
<tr class="alert alert-{{index $alertStateToRowClass .State}} alert_header">
<td><i class="icon-chevron-down"></i> <b>{{.Name}}</b> ({{len $activeAlerts}} active)</td>
</tr>
<tr class="alert_details">
<td>
<div>
<pre style="display:block; padding:9.5px; font-size:13px; color:#333; word-break:break-all; background-color:#f5f5f5; border:1px solid #ccc; border-radius:4px;" ><code>{{.HTMLSnippet pathPrefix}}</code></pre>
</div>
{{if $activeAlerts}}
<table class="table table-bordered table-hover table-sm alert_elements_table">
<tr class="">
<th>Labels</th>
<th>State</th>
<th>Active Since</th>
<th>Value</th>
</tr>
{{range $activeAlerts}}
<tr>
<td>
{{range $label, $value := .Labels.Map}}
<span class="badge badge-primary">{{$label}}="{{$value}}"</span>
{{end}}
</td>
<td><span class="alert alert-{{ .State | alertStateToClass }} state_indicator text-uppercase">{{.State}}</span></td>
<td>{{.ActiveAt.UTC}}</td>
<td>{{.Value}}</td>
</tr>
{{ if .Annotations.Map}}
<tr style="display:none" class="alert_annotations">
<th colspan="4">Annotations</th>
</tr>
<tr style="display:none" class="alert_annotations">
<td colspan="4">
<dl>
{{range $label, $value := .Annotations.Map}}
<dt>{{$label}}</dt>
<dd>{{$value}}</dd>
{{end}}
</dl>
</td>
</tr>
{{end}}
{{end}}
</table>
{{end}}
</td>
</tr>
{{else}}
{{$alertStateToRowClass := .AlertStateToRowClass}}
{{range .Groups}}
<tr>
<td>
No alerting rules defined
<td style="padding: 2px">
{{.File}} > {{.Name}}
</td>
</tr>
{{range .AlertingRules}}
{{$activeAlerts := .ActiveAlerts}}
<tr class="alert alert-{{index $alertStateToRowClass .State}} alert_header">
<td><i class="icon-chevron-down"></i> <b>{{.Name}}</b> ({{len $activeAlerts}} active)</td>
</tr>
<tr class="alert_details">
<td>
<div>
<pre style="display:block; padding:9.5px; font-size:13px; color:#333; word-break:break-all; background-color:#f5f5f5; border:1px solid #ccc; border-radius:4px;" ><code>{{.HTMLSnippet pathPrefix}}</code></pre>
</div>
{{if $activeAlerts}}
<table class="table table-bordered table-hover table-sm alert_elements_table">
<tr class="">
<th>Labels</th>
<th>State</th>
<th>Active Since</th>
<th>Value</th>
</tr>
{{range $activeAlerts}}
<tr>
<td>
{{range $label, $value := .Labels.Map}}
<span class="badge badge-primary">{{$label}}="{{$value}}"</span>
{{end}}
</td>
<td><span class="alert alert-{{ .State | alertStateToClass }} state_indicator text-uppercase">{{.State}}</span></td>
<td>{{.ActiveAt.UTC}}</td>
<td>{{.Value}}</td>
</tr>
{{ if .Annotations.Map}}
<tr style="display:none" class="alert_annotations">
<th colspan="4">Annotations</th>
</tr>
<tr style="display:none" class="alert_annotations">
<td colspan="4">
<dl>
{{range $label, $value := .Annotations.Map}}
<dt>{{$label}}</dt>
<dd>{{$value}}</dd>
{{end}}
</dl>
</td>
</tr>
{{end}}
{{end}}
</table>
{{end}}
</td>
</tr>
{{end}}
{{else}}
<tr>
<td>
No alerting rules defined
</td>
</tr>
{{end}}
</tbody>
</table>

View File

@ -500,12 +500,16 @@ func (h *Handler) Run(ctx context.Context) error {
}
func (h *Handler) alerts(w http.ResponseWriter, r *http.Request) {
alerts := h.ruleManager.AlertingRules()
alertsSorter := byAlertStateAndNameSorter{alerts: alerts}
sort.Sort(alertsSorter)
var groups []*rules.Group
for _, group := range h.ruleManager.RuleGroups() {
if group.HasAlertingRules() {
groups = append(groups, group)
}
}
alertStatus := AlertStatus{
AlertingRules: alertsSorter.alerts,
Groups: groups,
AlertStateToRowClass: map[rules.AlertState]string{
rules.StateInactive: "success",
rules.StatePending: "warning",
@ -927,24 +931,6 @@ func (h *Handler) executeTemplate(w http.ResponseWriter, name string, data inter
// AlertStatus bundles alerting rules and the mapping of alert states to row classes.
type AlertStatus struct {
AlertingRules []*rules.AlertingRule
Groups []*rules.Group
AlertStateToRowClass map[rules.AlertState]string
}
type byAlertStateAndNameSorter struct {
alerts []*rules.AlertingRule
}
func (s byAlertStateAndNameSorter) Len() int {
return len(s.alerts)
}
func (s byAlertStateAndNameSorter) Less(i, j int) bool {
return s.alerts[i].State() > s.alerts[j].State() ||
(s.alerts[i].State() == s.alerts[j].State() &&
s.alerts[i].Name() < s.alerts[j].Name())
}
func (s byAlertStateAndNameSorter) Swap(i, j int) {
s.alerts[i], s.alerts[j] = s.alerts[j], s.alerts[i]
}