From 6d15a82e89e990720771d75eeeafe5473fd7a969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Thu, 1 Jun 2017 22:13:12 -0700 Subject: [PATCH] Support multiple receivers --- Makefile | 4 +-- assets/templates/alertgroup.html | 4 +++ bindata_assetfs.go | 2 +- filters/filter_receiver.go | 46 ++++++++++++++++++++++++++++++++ filters/registry.go | 7 +++++ mapper/v062/alerts.go | 46 ++++++++++++++++++++++++-------- models/models.go | 2 ++ store/store.go | 6 ++--- timer.go | 38 +++++--------------------- views.go | 13 ++++++++- 10 files changed, 119 insertions(+), 49 deletions(-) create mode 100644 filters/filter_receiver.go diff --git a/Makefile b/Makefile index 94f9fef3b..6e070c9bc 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ ALERTMANAGER_URI := file://$(MOCK_PATH) # Listen port when running locally PORT := 8080 -SOURCES := $(wildcard *.go) $(wildcard */*.go) +SOURCES := $(wildcard *.go) $(wildcard */*.go) $(wildcard */*/*.go) ASSET_SOURCES := $(wildcard assets/*/* assets/*/*/*) GO_BINDATA_MODE := prod @@ -50,7 +50,7 @@ clean: .PHONY: run run: $(NAME) ALERTMANAGER_URI=$(ALERTMANAGER_URI) \ - COLOR_LABELS_UNIQUE="instance cluster" \ + COLOR_LABELS_UNIQUE="@receiver instance cluster" \ COLOR_LABELS_STATIC="job" \ DEBUG="$(GIN_DEBUG)" \ FILTER_DEFAULT="@state=active" \ diff --git a/assets/templates/alertgroup.html b/assets/templates/alertgroup.html index cb353beea..4274dcd61 100644 --- a/assets/templates/alertgroup.html +++ b/assets/templates/alertgroup.html @@ -76,6 +76,10 @@ <% }) %> <% var attrs = Alerts.GetLabelAttrs("@state", alert.state) %> <%= Templates.Render('buttonLabel', {elem: 'span', attrs: attrs, label: {key: '@state', value: alert.state, text: '@state: ' + alert.state}}) %> + + <% var attrs = Alerts.GetLabelAttrs("@receiver", alert.receiver) %> + <%= Templates.Render('buttonLabel', {elem: 'span', attrs: attrs, label: {key: '@receiver', value: alert.receiver, text: '@receiver: ' + alert.receiver}}) %> + <% if (alert.silencedBy.length == 0) { %> <% var labels = [] %> <% _.each(Alerts.SortMapByKey(alert.labels), function(label) { %> diff --git a/bindata_assetfs.go b/bindata_assetfs.go index e301acc62..cce49fdcc 100644 --- a/bindata_assetfs.go +++ b/bindata_assetfs.go @@ -138,7 +138,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _templatesAlertgroupHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x5a\xdd\x6f\x1b\x37\x12\x7f\xcf\x5f\x31\xdd\xab\xbb\x16\xac\x95\x92\xb7\x83\xa0\xd5\x9d\xdb\x2b\x82\xc3\x25\x38\xa0\xcd\x3d\x05\x81\x41\xed\x52\x12\x2d\x6a\x77\x43\x72\xdd\x0a\x86\xff\xf7\x03\x3f\x96\xcb\x2f\xc9\x72\xe3\x36\x0f\xb1\x44\x0e\x87\x9c\xe1\x7c\xfc\x66\xa8\x25\xaf\x18\xe9\x04\x88\x63\x87\xcb\x0c\x75\x1d\x25\x15\x12\xa4\x6d\xe6\xf7\xbc\x6d\x32\x20\x75\x99\x21\x8a\x99\x28\xb6\xac\xed\xbb\x42\x10\x41\x71\xb6\x7a\x03\xb0\xbc\x02\xb2\x81\xeb\xff\xae\xef\x71\x25\x66\x7b\x7c\xe4\xd7\x8a\x64\x46\xd1\x1a\x53\x3e\x99\x51\xdc\x6c\xc5\x0e\x56\xf0\x76\x02\x8f\x70\x25\xd7\xa8\x55\x0f\x88\xc1\x86\x50\x81\x19\x87\x12\x3e\x7f\x71\xa6\xee\x66\x18\x55\x3b\x8f\xcf\x14\x36\x7d\x53\xc9\x13\x5d\xab\x81\xbb\x07\x44\xa7\xa0\x3f\xee\xf1\x51\xb2\x36\xcc\x66\x5d\xcf\x77\xd7\x76\x06\x6e\x20\x2f\x73\xb8\x01\xbb\x6c\x02\x4f\x93\xe0\x1c\x6a\xa7\x0f\xa4\xd9\x43\x09\xf9\x3f\xbe\x2a\xfa\x81\xdd\x7d\x4b\x9a\xeb\x7c\x9a\x8f\x6b\x78\x87\x1a\xa8\x28\xe2\xbc\xcc\xba\x9e\xd2\x82\xe2\x8d\x00\x57\x3d\x94\x34\xfb\x4c\x53\x03\x2c\x11\xec\x18\xde\x94\xd9\xf2\xaa\x74\x76\xba\x5a\x65\xa0\xd4\x58\x66\xea\xbb\x68\x41\xec\x08\xd7\x7c\x34\x5d\x36\x85\x1a\x09\x54\x88\x76\xbb\x95\x74\xa2\x6d\xa9\x20\x5d\xa6\x47\x3b\x8a\x2a\x7c\xc0\x8d\x90\x13\x9d\xdd\x0e\x60\x49\x86\xd3\x6d\x10\x6c\x90\x3e\xcd\xdc\x1e\x67\x8e\x8c\x1c\x73\x29\x48\x42\xa6\x35\xaa\xb7\x18\x94\x64\x8c\x6c\x77\x62\x94\xe4\xaa\xd0\x07\x9b\xa9\x43\xf2\xe1\x6e\xaf\x12\x0c\x6b\xf2\x60\x75\x84\x1a\x4c\x1d\x93\x31\x8a\xff\x03\x66\xe3\xdb\xc7\xad\x3e\xc4\xaf\x2d\x13\x1f\x51\xf7\xe3\xf1\x3f\xf8\xe8\x33\x09\x8d\x26\xe0\x64\xaf\x1f\x09\xa1\x8c\xd0\x30\x7c\x8f\xc5\x07\x49\x7e\x2b\x87\xf5\x4a\x79\x42\x63\x6e\xb3\x07\x44\x7b\x3c\x09\x19\x95\xf0\x09\x1f\x3a\x8a\x04\xe6\xb3\x5f\x70\x53\x63\x76\x9d\xaf\x7b\x21\xda\x46\xf1\xca\xa7\xf0\x88\x29\x3e\x2c\x20\xaf\xc9\x43\x3e\x05\xf9\xe5\x27\xa9\x9f\x05\xe4\x8a\xaf\xe6\x5e\x50\xc2\x45\x3e\xd5\x47\x5a\xe8\x3f\x66\xe3\x85\xfe\xf3\x34\x09\xb4\xe1\x0e\xc8\xaf\x80\x29\xc7\x81\xce\x9c\xdb\x18\xb7\xd1\xfc\xb2\xd5\x72\x5e\x93\x07\x8f\x83\xbd\x50\x33\x31\x0c\x2e\xe7\x3a\x4e\xac\xde\xbc\x79\x69\xc4\x40\x4d\xd3\x0a\x45\xc0\x87\xb8\x71\xe6\x1a\xd5\xca\x99\xb3\xc6\xbd\xcb\x71\xd8\x8d\x28\x8e\x88\xbf\x61\x4a\x41\xfe\x57\xf0\x03\x8c\xd4\x85\x1c\x1a\x2d\x30\xf0\x92\xaf\x3d\xe6\x8a\xaa\x22\xac\xa2\x18\x04\xfe\x5d\x14\x87\x5e\xe0\xda\xfa\xa9\xbc\xe5\x91\x9d\xb4\x09\xe5\xc5\x97\xfb\xe8\x3c\x30\x7f\x87\x99\xb1\xaa\xc0\xd4\x0b\x08\x49\x9e\xbf\x6b\xd7\x95\x1d\x21\x5c\x73\xfd\x0c\x07\xc2\x39\x69\xb6\x0e\x7b\xd0\xec\xbf\x8c\x8c\x1c\x77\x3e\x63\x17\x93\x6f\x34\x0c\xed\xab\x17\xdb\xc4\xf3\xae\x6d\x74\xeb\x46\x82\xcf\xd6\x89\xbf\x40\x59\x42\xdf\xd4\x78\x43\x1a\x5c\x7b\xfa\x7e\x95\x60\xf0\x92\x40\x20\xd5\x7b\xa1\xab\x8f\xda\x7f\x0d\x95\xcb\xfd\x71\x23\xac\xd2\xa5\xd8\x15\xe5\x77\xa4\xa9\xe5\xc2\x96\xc9\x34\x48\x9a\x8a\xd4\xb8\x11\x85\x1d\x2d\x6a\xd4\x6c\x31\xcb\xed\x41\x94\x09\xab\x5b\xe1\x02\x09\x0c\x65\x59\x42\xc6\xfb\xae\x63\x98\x73\x5c\x67\x52\xbd\x97\xf0\xe5\x7d\x55\x61\xce\x73\x2b\xa3\x8d\x47\xde\x26\x5b\xdc\x60\x26\x17\xfc\xef\x97\x0f\xfe\xcd\x21\x2f\xb8\x41\x18\xe2\x8a\x1a\x6f\x50\x4f\x45\x36\xba\xc0\x98\x91\x63\xde\xd2\xa9\x47\x4a\x81\xd8\x16\x8b\x32\xbb\x5b\x53\xd4\xec\xdd\x09\x1d\x14\xde\xb7\x3a\x75\x63\x93\xb9\x79\xdb\xb3\x0a\x3b\x74\xc9\xf0\x10\x4c\x5f\x9c\xcb\xf1\xef\x02\xb3\x06\xd1\x20\xa9\x83\xd9\x36\xca\xf1\xae\xd7\x5a\xef\x32\x9e\x44\x9a\xbd\x8b\xab\x7a\x46\xa7\x2a\xea\xbd\x9e\x6e\x7b\x46\x5f\xa6\xcc\xe4\xa2\xbf\x46\x81\x32\xd8\x4a\xe9\x1d\xd1\x5d\x2d\x86\x90\xf1\x6c\x98\xc8\xfe\xa9\x1c\x22\x9b\x82\xe3\x1e\x0e\x87\xd7\x89\x11\x8f\x7b\x7c\x5c\x40\xae\xf7\xca\xa7\x3a\x80\x2f\xdc\x2d\xf5\x7d\x5a\x9a\x05\x48\x60\xeb\xcc\x3f\x79\x62\x39\xee\x4c\x28\x6e\x2a\x5c\xff\x78\x1c\x70\x58\x59\x06\x40\xcc\xa8\x41\xc7\x57\x0f\xc0\xbf\x56\x1c\x37\x9c\x34\xa1\x83\xea\x67\x11\xaa\x4f\x44\x61\x1f\x15\xb9\x29\xf1\x84\x19\x9b\x18\x04\x55\xcf\x78\xcb\x8a\xae\x25\x8d\xc0\xcc\x31\x33\x69\xa4\x2a\xbe\xea\x8b\xf2\x67\x94\x0d\xea\x93\x6a\x23\x36\xa7\x76\x8b\x87\xc4\x0a\xa5\x8a\x06\x1d\xb0\x1b\x8a\xcc\x52\x3b\x97\x5e\x3a\xf8\xc3\xa1\xad\x11\x4d\xcd\x1b\x4f\xfb\x9b\xb9\xcb\x8f\x8a\xce\xc3\xac\x81\x67\xac\x15\x60\xa2\x88\xef\x2c\xe0\xf9\x55\xaf\x75\x0a\x93\x97\xa0\x1d\x70\x6a\x0e\xa7\x32\x70\x43\xd2\x85\xc1\xc5\x7c\x43\x5b\x6c\x3e\x09\x6e\x45\x3e\x1b\x1d\x52\xc7\xf2\x17\x72\x57\xf5\x5c\x20\x26\xf8\xad\x8c\x01\xa3\xaa\x62\xeb\x29\x04\x2f\xe4\x60\x16\x40\xb5\x90\x87\xe5\xe0\x21\x29\x0f\xaa\xc6\xd9\x10\x76\xa4\xae\x71\xa3\xa2\x84\x9f\x3c\xbd\x43\x8d\x98\xdd\x84\x29\x33\xf2\x0d\xb0\xc0\x58\x8a\x46\x05\xfc\x80\x28\x1d\x4e\x69\x66\x8a\xaa\x3d\x48\x3d\xea\x5a\x0e\x22\x70\x69\xcc\xa5\x86\xf5\x71\xa1\x4e\xa4\x98\xf8\xc8\x2e\x0c\x30\x4e\x00\x30\x83\xff\xfe\x57\x00\xeb\x83\x90\x63\xc8\xa0\x1c\x3e\xf1\xcf\x76\xa5\x1f\x84\x64\x40\x33\x53\x61\x5c\x59\xd3\xb6\xda\x7f\xed\x5b\x81\x4f\xc8\x98\x05\x75\xa2\xc3\x6b\x76\x4f\x18\x0a\x31\x88\x21\x74\x6b\xfd\x80\x5c\x57\xfc\x7e\x02\xf4\x57\xbf\x20\x5b\x8d\x56\x37\xec\x62\xce\x1d\x9d\x68\x48\x62\x56\x92\x54\xd1\x70\x11\x33\xd7\x73\xcd\xc8\xa6\x6d\x05\x66\x01\x9f\x8a\x08\x1c\x9d\x14\xad\xd7\x2c\x74\xa2\x17\x05\x13\xcf\x5d\x87\x73\x26\x1d\x36\x2d\x11\xc3\x48\x48\x83\x0b\xc5\x56\x2a\x5a\xaf\x43\x21\xe6\xa1\x14\xcb\x79\x28\xec\x72\x3e\x5a\xd1\x5f\x53\x26\x15\x07\xd4\xb9\xa0\x5d\x0d\xde\x32\xe6\xe4\xdf\xd1\xd3\xd4\xe4\x47\xd4\x85\x29\x36\x02\x79\x43\x92\xbd\x65\x4c\xa7\xd9\x47\x8d\x1a\xe4\xff\x53\x50\x20\xc3\xa9\x7b\x0c\xca\x70\x12\xef\x14\x76\x44\xf0\x61\x48\x7e\x1e\x92\xaf\x93\x87\xdd\x4d\x78\xcb\xc4\xf5\x58\xce\x4f\x61\x1d\x97\x6f\x48\x31\x82\x25\xac\xd5\x87\x09\x30\x2c\x7a\xd6\xc0\xbb\x34\xdd\x2a\xa4\x2b\x62\x42\x85\xee\x24\xa1\x96\xff\x24\x43\x45\xb7\x0c\xe9\x3c\x86\x66\xec\x6d\x20\xe6\x9b\x54\xe3\x6b\xdd\xd6\x47\xb0\x71\xde\x84\x5a\xdc\x21\x55\x6e\x64\x71\xf7\xc2\x27\xcd\xc2\xe8\xb7\x27\x5d\x87\x6b\x85\x13\x65\x39\x75\x23\x51\x90\x19\x8c\x83\x9f\x19\x2f\x4b\x78\x17\x23\x2b\x8f\xd5\x4d\x09\xd9\x90\xe2\x9f\x6d\x31\x9c\x5c\xcb\xc3\xc5\xe3\xb7\xe7\x25\x4c\xb5\x21\x83\x30\x5c\xf8\x1b\xbb\x67\xf2\x73\xec\xa0\x2e\xa6\xd0\xb5\x54\xc1\x70\x59\x66\xfa\xbb\xa2\xb0\x5f\x2a\xd4\xe4\x02\x7a\x8e\x55\x67\x80\xf1\xaa\x65\x18\x94\x0f\x4d\x60\x87\x19\x06\xc4\x81\x08\xa8\x5b\xcc\x25\xa1\xac\x70\x5b\x26\x60\xcd\x30\xda\x93\x66\xab\x8a\x3f\xda\xb6\x9d\x65\xf8\x1b\x11\x3b\xc8\x8d\x91\x6c\x10\xe5\x12\x9e\x4b\xfe\xf7\x5f\x7b\xcc\x8e\x70\xc0\x62\xd7\xd6\x96\xbc\x28\xbc\x73\x7f\xef\xf8\xef\x2d\x63\x8e\xff\x12\x83\xfd\x53\x8d\x4c\x79\xdf\x56\xda\x15\xfc\x1d\x7e\xf8\x61\xf4\x38\xdb\x4d\x7d\x17\xb6\x53\x23\xb5\x3f\x53\xe6\xc5\x29\xc8\x35\xcb\x9f\xda\xbe\x11\x50\x46\x1b\x17\xe3\x45\xc4\xe1\xd7\xb3\x55\xc3\x21\x36\xd8\xe1\xdf\x8d\x63\x05\x9a\xf8\x6a\xa5\xf7\x8b\xf9\x9e\x4a\x75\xe7\xf9\xf0\x14\xa3\x28\xad\xfa\xe6\x06\x5e\x5c\x50\x57\x9e\x48\x9e\xa7\x12\xaf\xd5\xce\xcd\x4d\x62\xf2\x75\x5a\xd4\x56\xd1\x63\x98\x96\xf6\x90\xd4\x72\xdc\x2f\x16\x8c\x1c\x22\x77\x1d\x19\xbf\xb8\xa0\x3d\xd5\xfe\x56\xfb\x08\xb4\x7d\x41\x0b\xdc\x9e\xe2\x94\x15\xfb\x45\x84\xda\xa1\x92\x17\x9e\x90\x44\xc7\x18\x47\x43\xa9\x7d\x12\x57\xef\x01\xf2\x0b\xae\xfc\x4f\x6b\x14\x7a\x7b\x9f\x45\x6f\x61\x8d\xec\x16\x14\x03\x6e\xf9\xd6\x92\x22\x5b\xbd\x49\x47\x7e\x4d\x69\x1f\xc4\x66\xa4\x1e\x3b\xe9\x3b\xc4\x77\xee\x9c\xfc\x3e\xe2\x3b\xa7\x5d\xa9\xd2\xab\xcc\x81\x3a\xcf\x9a\x6b\xce\x93\x7d\x60\xd5\xee\x50\x6e\x3e\x43\x95\x20\x0f\x38\x7a\x59\x5a\x5e\x25\x99\xba\x2d\x4f\xf7\x4a\x93\xac\xc7\xde\xe7\x85\xec\x6d\xe7\x33\xea\xf3\x26\x90\x84\x2d\x09\xf5\x37\x07\xf2\xc6\xa0\x63\x87\x51\xad\x52\x93\xac\xd1\x2a\xac\x7a\x19\xee\xdd\xa7\x8c\x4f\x5d\xdc\x7b\x29\xd3\x27\x59\xdf\x49\x03\x54\x12\x2e\xf4\x45\x9c\xb0\x16\x1f\x8c\x7e\x44\x1d\x94\xf0\xf8\x14\x35\x8a\x2c\x14\x71\xf3\x70\xf8\xd6\xab\x31\x84\xfb\xd4\x23\x07\xa6\x40\x62\xf0\x22\xf5\x4f\x60\xa5\x61\xc7\x07\x72\x20\x02\x8a\x44\x34\x1b\xa1\x4a\x18\x5a\xa3\x76\xe8\xa5\xef\xcc\xe9\x00\xad\x40\x63\x09\xde\xbb\xb3\xee\xb7\x59\x3e\x27\xe2\x71\xfc\x50\x71\x77\xfe\xa1\x22\x58\x3f\xe8\xfd\xb3\x3c\x42\xbc\x2c\x9c\x36\x6d\x43\xbb\x91\x8f\xe8\xb5\xbc\x1a\xcf\xbf\x7d\x8a\xf3\xde\x08\xe4\x2d\x4b\x15\x28\x93\x89\x2b\x11\x81\xa2\x77\x53\x6d\x1c\xd2\x85\x3e\x69\x0d\x9e\xea\x55\x26\x01\x8f\x3d\x89\xe5\x70\x46\x01\x2e\xcd\x45\xcd\xd3\x53\x6a\x70\x55\x30\x32\x4d\xe8\xe1\x64\x06\x70\xa2\x98\x2a\x0f\x4a\xc8\xf3\xa4\x80\x04\x96\xc9\x27\x77\x63\xeb\x2e\x83\x53\x25\x46\x1e\x1d\x3f\x5d\xa2\x0c\xd1\x45\x7d\x89\xea\xe9\x8b\xf0\xfb\x70\xf4\xf3\xd1\xe5\x76\x7c\xd6\x95\x31\x46\x4d\x18\xcd\xa7\x32\xfb\x73\xec\x54\xb6\x8c\x38\x4d\xe1\x54\xec\xba\x94\xef\xcf\xe6\x95\xec\xb2\x33\x9e\xeb\x9e\x9f\x40\xb2\xcf\x1d\xc0\xb4\xd3\x62\xc9\x86\xbe\xd7\xc2\x7e\x3a\x71\xa6\x04\x6c\x0d\x50\x4a\x30\x10\xd4\x6c\xd1\x8f\x0b\xa4\x90\xdf\x7d\x3f\x23\xfc\xe7\x43\x27\x8e\xfa\xd7\x1b\xd6\x09\x27\x51\x94\xbe\xe0\xe2\x3e\xa2\x4e\x0a\x38\xf0\x58\xc0\xd8\xb6\x30\x81\x7b\x31\x7c\x88\x7e\xe8\x10\xf5\x59\xfe\x10\x5e\xd1\xb0\x50\x23\xaf\x42\xff\xea\xc7\xfd\x65\x93\x45\xaa\x51\x60\x91\x1e\xec\xcc\x4a\x17\x7e\xf2\xdf\x46\x35\x68\x4f\x2c\x1b\xe0\xfc\x63\x65\x30\x70\x3e\x05\x2e\x8e\x54\x86\xbd\xdc\xc6\x9b\xa5\xd4\xa0\xdc\x41\x96\x26\xc6\xf7\x86\x21\xbd\xe9\xd5\x4a\x69\x59\xb1\x9b\x55\x66\x68\x7c\x0d\x50\x2c\x4d\x83\x5b\x91\xa8\x01\x8f\x24\xfd\xa6\x31\xbe\x67\x14\x9a\xc0\xe8\x25\x45\xb0\xc7\x47\xe7\xcd\x63\xf8\x55\x44\x8a\xf2\x01\x51\x97\x72\xf8\x3d\x43\x40\x7b\xe2\x65\xc3\x7f\xd5\xd0\x56\xe2\xbc\x69\x8c\xb8\x7d\x7c\xc4\x5b\xce\x1d\x05\xba\x76\xf1\xff\x00\x00\x00\xff\xff\x63\x39\xae\xa0\xef\x26\x00\x00") +var _templatesAlertgroupHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x5a\xdd\x6f\x1b\x37\x12\x7f\xcf\x5f\x31\xdd\xab\xbb\x16\xac\x95\x92\xb7\x83\xa0\xd5\x9d\xdb\x2b\x82\xc3\x25\x38\xa0\xcd\x3d\x05\x81\x41\xed\x52\x12\x2d\x6a\x77\x43\x72\xdd\x0a\x86\xff\xf7\x03\x3f\x96\xcb\x2f\xc9\x72\xe3\x36\x0f\xb1\x44\x0e\x87\x9c\xe1\xcc\x6f\x3e\xa8\x25\xaf\x18\xe9\x04\x88\x63\x87\xcb\x0c\x75\x1d\x25\x15\x12\xa4\x6d\xe6\xf7\xbc\x6d\x32\x20\x75\x99\x21\x8a\x99\x28\xb6\xac\xed\xbb\x42\x10\x41\x71\xb6\x7a\x03\xb0\xbc\x02\xb2\x81\xeb\xff\xae\xef\x71\x25\x66\x7b\x7c\xe4\xd7\x8a\x64\x46\xd1\x1a\x53\x3e\x99\x51\xdc\x6c\xc5\x0e\x56\xf0\x76\x02\x8f\x70\x25\xd7\xa8\x55\x0f\x88\xc1\x86\x50\x81\x19\x87\x12\x3e\x7f\x71\xa6\xee\x66\x18\x55\x3b\x8f\xcf\x14\x36\x7d\x53\xc9\x13\x5d\xab\x81\xbb\x07\x44\xa7\xa0\x3f\xee\xf1\x51\xb2\x36\xcc\x66\x5d\xcf\x77\xd7\x76\x06\x6e\x20\x2f\x73\xb8\x01\xbb\x6c\x02\x4f\x93\xe0\x1c\x6a\xa7\x0f\xa4\xd9\x43\x09\xf9\x3f\xbe\x2a\xfa\x81\xdd\x7d\x4b\x9a\xeb\x7c\x9a\x8f\x6b\x78\x87\x1a\xa8\x28\xe2\xbc\xcc\xba\x9e\xd2\x82\xe2\x8d\x00\x57\x3d\x94\x34\xfb\x4c\x53\x03\x2c\x11\xec\x18\xde\x94\xd9\xf2\xaa\x74\x76\xba\x5a\x65\xa0\xd4\x58\x66\xea\xbb\x68\x41\xec\x08\xd7\x7c\x34\x5d\x36\x85\x1a\x09\x54\x88\x76\xbb\x95\x74\xa2\x6d\xa9\x20\x5d\xa6\x47\x3b\x8a\x2a\x7c\xc0\x8d\x90\x13\x9d\xdd\x0e\x60\x49\x86\xd3\x6d\x10\x6c\x90\x3e\xcd\xdc\x1e\x67\x8e\x8c\x1c\x73\x29\x48\x42\xa6\x35\xaa\xb7\x18\x94\x64\x8c\x6c\x77\x62\x94\xe4\xaa\xd0\x07\x9b\xa9\x43\xf2\xe1\x6e\xaf\x12\x0c\x6b\xf2\x60\x75\x84\x1a\x4c\x1d\x93\x31\x8a\xff\x03\x66\xe3\xdb\xc7\xad\x3e\xc4\xaf\x2d\x13\x1f\x51\xf7\xe3\xf1\x3f\xf8\xe8\x33\x09\x8d\x26\xe0\x64\xaf\x1f\x09\xa1\x8c\xd0\x30\x7c\x8f\xc5\x07\x49\x7e\x2b\x87\xf5\x4a\x79\x42\x63\x6e\xb3\x07\x44\x7b\x3c\x09\x19\x95\xf0\x09\x1f\x3a\x8a\x04\xe6\xb3\x5f\x70\x53\x63\x76\x9d\xaf\x7b\x21\xda\x46\xf1\xca\xa7\xf0\x88\x29\x3e\x2c\x20\xaf\xc9\x43\x3e\x05\xf9\xe5\x27\xa9\x9f\x05\xe4\x8a\xaf\xe6\x5e\x50\xc2\x45\x3e\xd5\x47\x5a\xe8\x3f\x66\xe3\x85\xfe\xf3\x34\x09\xb4\xe1\x0e\xc8\xaf\x80\x29\xc7\x81\xce\x9c\xdb\x18\xb7\xd1\xfc\xb2\xd5\x72\x5e\x93\x07\x8f\x83\xbd\x50\x33\x31\x0c\x2e\xe7\x1a\x27\x56\x6f\xde\xbc\x14\x31\x50\xd3\xb4\x42\x11\xf0\x01\x37\xce\x5c\xa3\x5a\x39\x73\xd6\xb8\x77\x39\x0e\xbb\x88\xe2\x88\xf8\x1b\xa6\x14\xe4\x7f\x05\x3f\xc0\x48\x5d\xc8\xa1\xd1\x02\x03\x2f\xf9\xda\x63\xae\xa8\x2a\xc2\x2a\x8a\x41\xe0\xdf\x45\x71\xe8\x05\xae\xad\x9f\xca\x5b\x1e\xd9\x49\x9b\x50\x5e\x7c\xb9\x8f\xce\x03\xf3\x77\x98\x19\xab\x0a\x4c\xbd\x80\x90\xe4\xf9\xbb\x76\x5d\xd9\x11\xc2\x35\xd7\xcf\x70\x20\x9c\x93\x66\xeb\xb0\x07\xcd\xfe\xcb\xc8\xc8\x71\xe7\x33\x76\x31\xf9\x46\xc3\xd0\xbe\x7a\xb1\x4d\x3c\xef\xda\x46\xb7\x2e\x12\x7c\xb6\x4e\xfc\x05\xca\x12\xfa\xa6\xc6\x1b\xd2\xe0\xda\xd3\xf7\xab\x80\xc1\x4b\x80\x40\xaa\xf7\x42\x57\x1f\xb5\xff\x1a\x2a\x97\xfb\xe3\x46\x58\xa5\x4b\xb1\x2b\xca\xef\x48\x53\xcb\x85\x2d\x93\x61\x90\x34\x15\xa9\x71\x23\x0a\x3b\x5a\xd4\xa8\xd9\x62\x96\xdb\x83\x28\x13\x56\xb7\xc2\x05\x12\x18\xca\xb2\x84\x8c\xf7\x5d\xc7\x30\xe7\xb8\xce\xa4\x7a\x2f\xe1\xcb\xfb\xaa\xc2\x9c\xe7\x56\x46\x8b\x47\xde\x26\x5b\xdc\x60\x26\x17\xfc\xef\x97\x0f\xfe\xcd\x21\x0f\xdc\x20\x84\xb8\xa2\xc6\x1b\xd4\x53\x91\x8d\x2e\x30\x46\xe4\x98\xb7\x74\xea\x91\x52\x20\xb6\xc5\xa2\xcc\xee\xd6\x14\x35\x7b\x77\x42\x83\xc2\xfb\x56\x87\x6e\x6c\x22\x37\x6f\x7b\x56\x61\x87\x2e\x09\x0f\xc1\xf4\xc5\xb1\x1c\xff\x2e\x30\x6b\x10\x0d\x82\x3a\x98\x6d\xa3\x18\xef\x7a\xad\xf5\x2e\xe3\x49\xa4\xd9\xbb\x79\x55\xcf\xe8\x54\xa1\xde\xeb\xe9\xb6\x67\xf4\x65\xca\x4c\x2e\xfa\x6b\x14\x28\xc1\x56\x4a\xef\x88\xee\x6a\x31\x4c\x19\xcf\xc2\x44\xf6\x4f\xe5\x10\xd9\x14\x1c\xf7\x70\x38\xbc\x0e\x46\x3c\xee\xf1\x71\x01\xb9\xde\x2b\x9f\x6a\x00\x5f\xb8\x5b\xea\xfb\xb4\x34\x0b\x90\x89\xad\x33\xff\xa4\xc5\x7a\x81\x5c\x0c\x57\x98\x3c\x60\x66\x45\x1b\x06\xfe\x34\xe9\x86\x0d\x42\x01\x87\xf1\x51\xc6\x61\xc4\x15\x73\x18\x0b\x24\x75\x90\x8b\x50\xdc\x54\xb8\xfe\xf1\x38\xa4\x9c\x65\x19\xe4\x9c\x46\x33\x3a\x94\x78\xb5\xca\x6b\x85\x2c\xc3\x49\x13\x3a\x05\xcc\x2c\x2a\x60\x12\x01\xc7\x4f\x00\xdd\xe8\x7f\xc2\x63\x0d\xdc\x42\xd5\x33\xde\xb2\xa2\x6b\x49\x23\x30\x73\x3c\x4a\xfa\xa3\x0a\x25\xfa\xd6\xfc\x19\xe5\x6e\xfa\xa4\xda\x5f\xcd\xa9\xdd\x3a\x29\xb1\x42\xa9\xa2\x41\x07\xec\xa2\xae\x59\x6a\xe7\xd2\x4b\x07\xd7\x3f\xb4\x35\xa2\xa9\x79\x03\x2a\x7f\x33\x77\xf9\x51\xd1\x79\xe9\x79\x00\x02\x6b\x95\x1b\x52\xc4\x77\x36\xb7\xfb\x55\xaf\x75\x6a\xb0\x97\x24\x76\xe0\x94\x57\x4e\x11\xe4\xa2\xef\x85\x38\x6a\xbe\xa1\x2d\x36\x9f\x04\xb7\x22\x9f\x05\xc2\xd4\xb1\xfc\x85\xdc\x55\x3d\x17\x88\x09\x7e\x2b\xe1\x6e\x54\x55\x6c\x3d\x85\xe0\x85\x1c\xcc\x82\xac\x34\xe4\x61\x39\x78\x49\xa3\x97\x95\xc7\x81\x1f\x76\xa4\xae\x71\xa3\x20\xc3\xcf\x13\xbc\x43\x8d\xe5\x89\x41\x64\x33\xf2\x0d\x19\x90\xb1\x14\x9d\x00\xf1\x03\xa2\x74\x38\xa5\x99\x29\xaa\xf6\x20\xf5\xa8\xcb\x56\x88\xf2\x68\x63\x2e\x35\xac\x8f\x0b\x75\x22\xc5\xc4\x4f\x62\x43\x80\x71\x00\xc0\x0c\xfe\xfb\x5f\x41\x05\x13\x40\x8e\x21\x83\x72\xf8\xc4\x3f\xdb\x95\x3e\x08\x49\x40\x33\x53\x21\xae\xac\x69\x5b\xed\xbf\xf6\xad\xc0\x27\x64\xcc\x82\x92\xd8\xe1\x35\xbb\x27\x0c\x85\xe9\x96\x21\x74\xdb\x1a\x01\xb9\x6e\x6e\xf8\xb1\xde\x5f\xfd\x82\xc0\x3c\x5a\xdd\xb0\x8b\x39\x77\x74\xa2\x21\x5e\x5b\x49\x52\xf5\xd1\x45\xcc\x5c\xcf\x35\x23\x9b\xb6\x15\x98\x05\x7c\x2a\x22\x70\x74\x52\xb4\x5e\xb3\xd0\x89\x5e\x04\x26\x9e\xbb\x0e\xe7\x4c\x3a\x6c\x5a\x22\x86\x91\x90\x06\x17\x8a\xad\x54\xb4\x5e\x87\x42\xcc\x43\x29\x96\xf3\x50\xd8\xe5\x7c\xb4\xa2\xbf\xa6\x22\x2c\x0e\xa8\x73\xeb\x13\x35\x78\xcb\x98\x13\x7f\x47\x4f\x53\x93\x1f\x51\x17\x86\xd8\x28\x9f\x1d\x82\xec\x2d\x63\x3a\xcc\x3e\xea\xe4\x41\xfe\x3f\x05\x95\x71\x38\x25\x9e\xc9\x37\x9c\xc0\x3b\x85\x1d\x11\x7c\x18\x92\x9f\x87\xe0\xeb\xc4\x61\x77\x13\xde\x32\x71\x3d\x76\x2e\xa6\xb0\x8e\x2b\x55\xa4\x18\xc1\x12\xd6\xea\xc3\x04\x18\x16\x3d\x6b\xe0\x5d\x9a\x6e\x15\xd2\x15\x31\xa1\x4a\x64\x25\xa1\x96\xff\x24\x43\x45\xb7\x0c\xe9\x3c\x86\x66\xec\x6d\x20\xe6\x9b\x54\x8f\x6f\xdd\xd6\x47\xb0\x38\x6f\xa0\x16\x77\x48\x55\x56\x59\xdc\xa8\xf1\x49\xb3\x10\xfd\xf6\xa4\xeb\x70\xad\x92\x46\x59\x39\xde\xc8\x2c\xc8\x0c\xc6\xe0\x67\xc6\xcb\x12\xde\xc5\x99\x95\xc7\xea\xa6\x84\x6c\x08\xf1\xcf\x76\x53\x4e\xae\xe5\xe1\xe2\xf1\xdb\xf3\x12\xa6\x3a\xae\x01\x0c\x17\xfe\xc6\xee\x99\xfc\x18\x3b\xa8\x8b\xa9\x54\x5b\xaa\x60\xb8\x2c\x33\xfd\x5d\x51\xd8\x2f\x15\x6a\x72\x01\x3d\xc7\xaa\x09\xc2\x78\xd5\x32\x0c\xca\x87\x26\xb0\xc3\x0c\x03\xe2\x40\x04\xd4\x2d\xe6\x92\x50\x16\xf3\x2d\x13\xb0\x66\x18\xed\x49\xb3\x55\x75\x2e\x6d\xdb\xce\x32\xfc\x8d\x88\x1d\xe4\xc6\x48\x36\x88\x72\x59\x89\x48\xfe\xf7\x5f\x7b\xcc\x8e\x70\xc0\x62\xd7\xd6\x96\xbc\x28\xbc\x73\x7f\xef\xf8\xef\x2d\x63\x8e\xff\x12\x53\x08\xa4\x7a\xb6\xf2\xbe\xad\xb4\x2b\xf8\x3b\xfc\xf0\xc3\xe8\x71\xb6\x71\xfc\x2e\xec\x1c\x47\x6a\x7f\xa6\xa2\x8d\x43\x90\x6b\x96\x3f\xb5\x7d\x23\xa0\x8c\x36\x2e\xc6\x8b\x88\xe1\xd7\xb3\x55\xc3\x21\x36\xd8\xe1\xdf\x8d\x63\x05\x9a\xf8\x6a\xa5\xf7\x8b\xf9\x9e\x0a\x75\xe7\xf9\xf0\x14\xa3\x28\xac\xfa\xe6\x06\x1e\x2e\xa8\x2b\x4f\x04\xcf\x53\x81\xd7\x6a\xe7\xe6\x26\x31\xf9\x3a\xdd\x78\xab\xe8\x11\xa6\xa5\x3d\x24\xb5\x1c\xb7\xc6\x05\x23\x87\xc8\x5d\x47\xc6\x2f\xae\x6e\x4f\x75\xfa\xd5\x3e\x02\x6d\x5f\xd0\xed\xb7\xa7\x38\x65\xc5\x7e\x11\xa1\x76\xa8\xe4\x85\x27\x24\xd1\x18\xe3\x68\x28\xb5\x4f\xe2\xea\xbd\x84\xfc\x82\x2b\xff\xd3\x7a\xa2\xde\xde\x67\xb3\xb7\xb0\x46\x76\x0b\x8a\x21\x6f\xf9\xd6\x92\x22\x5b\xbd\x49\x23\xbf\xa6\xb4\x6f\x7f\x33\x52\x8f\x8f\x06\x3b\xc4\x77\xee\x9c\xfc\x3e\xe6\x77\x4e\x67\x56\x85\x57\x19\x03\x75\x9c\x35\xd7\x9c\x27\x5b\xde\xaa\xb3\xa3\xdc\x7c\x86\x2a\x41\x1e\x70\xf4\x88\xb6\xbc\x4a\x32\x75\xbb\xbb\xee\x95\x26\x59\x8f\x6d\xde\x0b\xd9\xdb\x26\x6f\xd4\xd2\x4e\x64\x12\xb6\x24\xd4\xdf\x9c\x94\x37\x4e\x3a\x76\x18\xd5\x2a\x34\xc9\x1a\xad\xc2\xaa\x97\xe1\xde\x7d\xca\xf8\xd4\xc5\xbd\x97\x32\x7d\x92\xf5\x9d\x34\x40\x25\xe1\x42\x5f\xc4\x09\x6b\xf1\x93\xd1\x8f\xa8\x83\x12\x1e\x9f\xa2\x46\x91\x4d\x45\xdc\x38\x1c\x3e\x6b\xeb\x1c\xc2\x7d\xd5\x92\x03\x53\x20\x71\xf2\x22\xf5\x4f\x60\xa5\xd3\x8e\x0f\xe4\x40\x04\x14\x09\x34\x1b\x53\x95\x10\x5a\xa3\xce\xef\xa5\x4f\xea\x69\x80\x56\x49\x63\x09\xde\x13\xbb\xee\xb9\x59\x3e\x27\xf0\x38\x7e\x93\xb9\x3b\xff\x26\x13\xac\x1f\xf4\xfe\x59\x1e\x21\x5e\x16\x4e\x9b\x1e\xa2\xdd\xc8\xcf\xe8\xb5\xbc\x3a\x9f\x7f\xfb\x14\xc7\xbd\x31\x91\xb7\x2c\x15\x50\x26\x03\x57\x02\x81\xa2\x27\x62\x6d\x1c\xd2\x85\x3e\x69\x0d\x9e\x6a\xcb\x26\x13\x1e\x7b\x12\xcb\xe1\x8c\x02\x5c\x9a\x8b\xfa\xc4\xa7\xd4\xe0\xaa\x60\x64\x9a\xd0\xc3\xc9\x08\xe0\xa0\x98\x2a\x0f\x4a\xc8\xf3\xa4\x80\x04\x96\xc9\x5f\x17\x18\x5b\x77\x19\x9c\x2a\x31\xf2\xe8\xf8\xe9\x12\x65\x40\x17\xf5\x25\xaa\xa7\x2f\xca\xdf\x87\xa3\x9f\x47\x97\xdb\xf1\x05\x5b\x62\x8c\x9a\x30\x9a\x4f\x45\xf6\xe7\xd8\xa9\x68\x19\x71\x9a\xc2\x29\xec\xba\x94\xef\xcf\xe6\x41\xf0\xb2\x33\x9e\xeb\x9e\x9f\xc8\x64\x9f\x3b\x80\x69\xa7\xc5\x92\x0d\x7d\xaf\x85\xfd\x74\xe2\x4c\x89\xb4\x35\xc8\x52\x82\x81\xa0\x66\x8b\x7e\x47\x21\x85\xfc\xee\xfb\x19\xe1\x3f\x1f\x3a\x71\xd4\x3f\x54\xb1\x4e\x38\x89\x50\xfa\x82\x8b\xfb\x88\x3a\x29\xe0\xc0\x63\x01\x63\xdb\xc2\x00\xf7\x62\xf8\x10\xfd\xa6\x23\xea\xb3\xfc\xa1\x7c\x45\xa7\x85\x3a\xf3\x2a\xf4\x0f\x9c\xdc\x1f\x71\xd9\x4c\x35\x02\x16\xe9\xc1\xce\xac\x74\xe1\x27\xff\x19\x58\x27\xed\x89\x65\x43\x3a\xff\x58\x99\x1c\x38\x9f\x02\x17\x47\x2a\x61\x2f\xb7\x78\xb3\x94\x1a\x94\x3b\xc8\xd2\xc4\xf8\xde\x30\xa4\x37\xbd\x5a\x29\x2d\x2b\x76\xb3\xca\x0c\x8d\xaf\x01\x8a\xa5\x69\x70\x2b\x12\x35\xe0\x91\xa4\xdf\x34\xc6\xf7\x8c\x42\x13\x18\xbd\xa4\x08\xf6\xf8\xe8\xbc\x79\x0c\x3f\x00\x49\x51\x3e\x20\xea\x52\x0e\x3f\xdd\x08\x68\x4f\xbc\x6c\xf8\xaf\x1a\xda\x4a\x9c\x37\x8d\x31\x6f\x1f\xdf\x2b\x97\x73\x47\x81\xae\x5d\xfc\x3f\x00\x00\xff\xff\x3b\x3d\x4a\x16\xda\x27\x00\x00") func templatesAlertgroupHtmlBytes() ([]byte, error) { return bindataRead( diff --git a/filters/filter_receiver.go b/filters/filter_receiver.go new file mode 100644 index 000000000..e840642a5 --- /dev/null +++ b/filters/filter_receiver.go @@ -0,0 +1,46 @@ +package filters + +import ( + "fmt" + "strings" + + "github.com/cloudflare/unsee/models" +) + +type receiverFilter struct { + alertFilter +} + +func (filter *receiverFilter) Match(alert *models.Alert, matches int) bool { + if filter.IsValid { + isMatch := filter.Matcher.Compare(alert.Receiver, filter.Value) + if isMatch { + filter.Hits++ + } + return isMatch + } + e := fmt.Sprintf("Match() called on invalid filter %#v", filter) + panic(e) +} + +func newreceiverFilter() FilterT { + f := receiverFilter{} + return &f +} + +func receiverAutocomplete(name string, operators []string, alerts []models.Alert) []models.Autocomplete { + tokens := []models.Autocomplete{} + for _, operator := range operators { + for _, alert := range alerts { + tokens = append(tokens, makeAC( + name+operator+alert.Receiver, + []string{ + name, + strings.TrimPrefix(name, "@"), + name + operator, + }, + )) + } + } + return tokens +} diff --git a/filters/registry.go b/filters/registry.go index 84ad9038f..37d770409 100644 --- a/filters/registry.go +++ b/filters/registry.go @@ -47,6 +47,13 @@ var AllFilters = []filterConfig{ Factory: newstateFilter, Autocomplete: stateAutocomplete, }, + filterConfig{ + Label: "@receiver", + LabelRe: regexp.MustCompile("^@receiver$"), + SupportedOperators: []string{regexpOperator, negativeRegexOperator, equalOperator, notEqualOperator}, + Factory: newreceiverFilter, + Autocomplete: receiverAutocomplete, + }, filterConfig{ Label: "@age", LabelRe: regexp.MustCompile("^@age$"), diff --git a/mapper/v062/alerts.go b/mapper/v062/alerts.go index bfda668a3..b20107330 100644 --- a/mapper/v062/alerts.go +++ b/mapper/v062/alerts.go @@ -34,16 +34,24 @@ type alert struct { type alertsGroups struct { Labels map[string]string `json:"labels"` Blocks []struct { - Alerts []alert `json:"alerts"` + Alerts []alert `json:"alerts"` + RouteOps struct { + Receiver string `json:"receiver"` + } `json:"routeOpts"` } `json:"blocks"` } type alertsGroupsAPISchema struct { Status string `json:"status"` - Groups []alertsGroups `json:"data"` + Data []alertsGroups `json:"data"` Error string `json:"error"` } +type alertsGroupReceiver struct { + Name string + Groups []models.AlertGroup +} + // AlertMapper implements Alertmanager API schema type AlertMapper struct { mapper.AlertMapper @@ -59,6 +67,7 @@ func (m AlertMapper) IsSupported(version string) bool { // It will only return alerts or error (if any) func (m AlertMapper) GetAlerts() ([]models.AlertGroup, error) { groups := []models.AlertGroup{} + receivers := map[string]alertsGroupReceiver{} resp := alertsGroupsAPISchema{} url, err := transport.JoinURL(config.Config.AlertmanagerURI, "api/v1/alerts/groups") @@ -75,9 +84,16 @@ func (m AlertMapper) GetAlerts() ([]models.AlertGroup, error) { return groups, errors.New(resp.Error) } - for _, g := range resp.Groups { - alertList := models.AlertList{} - for _, b := range g.Blocks { + for _, d := range resp.Data { + for _, b := range d.Blocks { + rcv, found := receivers[b.RouteOps.Receiver] + if !found { + rcv = alertsGroupReceiver{ + Name: b.RouteOps.Receiver, + } + receivers[b.RouteOps.Receiver] = rcv + } + alertList := models.AlertList{} for _, a := range b.Alerts { inhibitedBy := []string{} if a.Status.InhibitedBy != nil { @@ -87,7 +103,8 @@ func (m AlertMapper) GetAlerts() ([]models.AlertGroup, error) { if a.Status.SilencedBy != nil { silencedBy = a.Status.SilencedBy } - us := models.Alert{ + a := models.Alert{ + Receiver: rcv.Name, Annotations: a.Annotations, Labels: a.Labels, StartsAt: a.StartsAt, @@ -97,14 +114,21 @@ func (m AlertMapper) GetAlerts() ([]models.AlertGroup, error) { InhibitedBy: inhibitedBy, SilencedBy: silencedBy, } - alertList = append(alertList, us) + alertList = append(alertList, a) } + ug := models.AlertGroup{ + Receiver: rcv.Name, + Labels: d.Labels, + Alerts: alertList, + } + rcv.Groups = append(rcv.Groups, ug) + receivers[rcv.Name] = rcv } - ug := models.AlertGroup{ - Labels: g.Labels, - Alerts: alertList, + } + for _, rcv := range receivers { + for _, ag := range rcv.Groups { + groups = append(groups, ag) } - groups = append(groups, ug) } return groups, nil } diff --git a/models/models.go b/models/models.go index 8f2a83301..467f5d92f 100644 --- a/models/models.go +++ b/models/models.go @@ -56,6 +56,7 @@ type Alert struct { SilencedBy []string `json:"silencedBy"` InhibitedBy []string `json:"inhibitedBy"` // unsee fields + Receiver string `json:"receiver"` Links map[string]string `json:"links"` Fingerprint string `json:"-"` } @@ -100,6 +101,7 @@ func (a AlertList) Less(i, j int) bool { // There is a hash computed from all alerts, it's used by UI to quickly tell // if there was any change in a group and it needs to refresh it type AlertGroup struct { + Receiver string `json:"receiver"` Labels map[string]string `json:"labels"` Alerts AlertList `json:"alerts"` ID string `json:"id"` diff --git a/store/store.go b/store/store.go index 2d639a6ce..f13076f19 100644 --- a/store/store.go +++ b/store/store.go @@ -8,7 +8,7 @@ import ( type dataStore struct { Lock sync.RWMutex - Alerts []models.AlertGroup + Groups []models.AlertGroup Silences map[string]models.Silence Colors models.LabelsColorMap Autocomplete []models.Autocomplete @@ -35,10 +35,10 @@ func (ds *dataStore) SetSilences(s map[string]models.Silence) { } // Update will lock the store and update internal data -func (ds *dataStore) Update(alerts []models.AlertGroup, colors models.LabelsColorMap, autocomplete []models.Autocomplete) { +func (ds *dataStore) Update(groups []models.AlertGroup, colors models.LabelsColorMap, autocomplete []models.Autocomplete) { ds.Lock.Lock() defer ds.Lock.Unlock() - ds.Alerts = alerts + ds.Groups = groups ds.Colors = colors ds.Autocomplete = autocomplete } diff --git a/timer.go b/timer.go index e623ddec6..86ffabdb0 100644 --- a/timer.go +++ b/timer.go @@ -12,9 +12,9 @@ import ( "github.com/cloudflare/unsee/models" "github.com/cloudflare/unsee/store" "github.com/cloudflare/unsee/transform" + "github.com/cnf/structhash" log "github.com/Sirupsen/logrus" - "github.com/cnf/structhash" "github.com/prometheus/client_golang/prometheus" ) @@ -66,53 +66,28 @@ func PullFromAlertmanager() { metricAlerts.With(prometheus.Labels{"state": state}).Set(0) } - uniqueAlerts := map[string]bool{} - log.Infof("Processing alert groups (%d)", len(alertGroups)) for _, ag := range alertGroups { // used to generate group content hash agHasher := sha1.New() - alerts := map[string]models.Alert{} - - ignoredLabels := []string{} - for _, il := range config.Config.StripLabels { - ignoredLabels = append(ignoredLabels, il) - } - + alerts := models.AlertList{} for _, alert := range ag.Alerts { // generate alert fingerprint from a raw, unaltered alert object alert.Fingerprint = fmt.Sprintf("%x", structhash.Sha1(alert, 1)) - // skip global duplicated alerts (shared between multiple groups) - if _, found := uniqueAlerts[alert.Fingerprint]; found { - continue - } - // skip group duplicated alerts (shared between multiple blocks) - if _, found := alerts[alert.Fingerprint]; found { - continue - } - - // mark this alert as seen - uniqueAlerts[alert.Fingerprint] = true - alert.Annotations, alert.Links = transform.DetectLinks(alert.Annotations) - alert.Labels = transform.StripLables(ignoredLabels, alert.Labels) - - alerts[alert.Fingerprint] = alert + alert.Labels = transform.StripLables(config.Config.StripLabels, alert.Labels) io.WriteString(agHasher, alert.Fingerprint) // alert group hasher + transform.ColorLabel(colorStore, "@receiver", alert.Receiver) for k, v := range alert.Labels { transform.ColorLabel(colorStore, k, v) } + alerts = append(alerts, alert) - } - - // reset alerts, we need to deduplicate - ag.Alerts = []models.Alert{} - for _, alert := range alerts { - ag.Alerts = append(ag.Alerts, alert) + // update internal metrics metricAlerts.With(prometheus.Labels{"state": alert.State}).Inc() } @@ -126,6 +101,7 @@ func PullFromAlertmanager() { ag.ID = fmt.Sprintf("%x", structhash.Sha1(ag.Labels, 1)) // Hash is a checksum of all alerts, used to tell when any alert in the group changed ag.Hash = fmt.Sprintf("%x", agHasher.Sum(nil)) + alertStore = append(alertStore, ag) } diff --git a/views.go b/views.go index 624dfbb74..497dbf587 100644 --- a/views.go +++ b/views.go @@ -133,9 +133,10 @@ func alerts(c *gin.Context) { store.Store.Lock.RLock() var matches int - for _, ag := range store.Store.Alerts { + for _, ag := range store.Store.Groups { agCopy := models.AlertGroup{ ID: ag.ID, + Receiver: ag.Receiver, Labels: ag.Labels, Alerts: []models.Alert{}, StateCount: map[string]int{}, @@ -175,6 +176,16 @@ func alerts(c *gin.Context) { countLabel(counters, "@state", alert.State) + countLabel(counters, "@receiver", alert.Receiver) + if ck, foundKey := store.Store.Colors["@receiver"]; foundKey { + if cv, foundVal := ck[alert.Receiver]; foundVal { + if _, found := colors["@receiver"]; !found { + colors["@receiver"] = map[string]models.LabelColors{} + } + colors["@receiver"][alert.Receiver] = cv + } + } + agCopy.StateCount[alert.State]++ for key, value := range alert.Labels {