From aa657ea21675a1f51eeb63a0fe0a228867c5bb50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Wed, 20 Feb 2019 20:59:54 +0000 Subject: [PATCH] feat(backend): allow configuring default grid sort options This will allow UI to get the defaults for grid sorting via the API --- docs/CONFIGURATION.md | 57 ++++++++++++++++++++++++++++++++++ internal/config/config.go | 12 +++++++ internal/config/config_test.go | 5 +++ internal/config/models.go | 7 +++++ internal/models/api.go | 8 +++++ views.go | 5 +++ 6 files changed, 94 insertions(+) diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 868700096..7685293bd 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -245,6 +245,61 @@ filters: default: [] ``` +### Grid + +`grid` section allows customizing how alert grid is rendered in the UI. +Sorting configuration can be overridden by each user via UI settings. +Syntax: + +```YAML +grid: + sorting: + order: string + reverse: bool + label: string +``` + +- `sorting:order` - default sort order for alert grid, valid values are: + - `disabled` - no sorting, alert groups are rendered in the order they are + returned by the API + - `startsAt` - sort by alert timestamps, most recent alert in each group will + be used when comparing each group + - `label` - sort by labels, if the label used for sorting is not shared by + all alerts in a group then the first alert in the group will be queried for + it +- `sorting:reverse` - default value for reversed sort order +- `sorting:label` - label name for sorting when `grid:sorting:order` is set + to `label`. Labels can be assigned custom values used only by sorting via + `labels:sorting:valueMapping`, see [Labels](#Labels) section for details. + +Defaults: + +```YAML +grid: + sorting: + order: startsAt + reverse: true + label: alertname +``` + +Example with sorting using `severity` label, with extra option to map severity +labels to numeric values for sorting: + +```YAML +grid: + sorting: + order: label + reverse: false + label: severity +labels: + sorting: + valueMapping: + severity: + critical: 1 + warning: 2 + info: 3 +``` + ### Labels `labels` section allows configuring how alert labels will be rendered in the @@ -293,6 +348,8 @@ labels: To allow for more natural sorting `sorting:valueMapping` can be used to map label values to integer values which will be used for sorting instead of original string values. + Note: this option is not available via environment variables, you can only set + it via the config file. Example with static color for the `job` label (every `job` label will have the same color regardless of the value) and unique color for the `@receiver` label diff --git a/internal/config/config.go b/internal/config/config.go index 38afd7a5c..ec42b1b71 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "github.com/prymitive/karma/internal/slices" "github.com/prymitive/karma/internal/uri" "github.com/spf13/pflag" "github.com/spf13/viper" @@ -60,6 +61,10 @@ func init() { "List of labels to keep, all other labels will be stripped") pflag.StringSlice("labels.strip", []string{}, "List of labels to ignore") + pflag.String("grid.sorting.order", "startsAt", "Default sort order for alert grid") + pflag.Bool("grid.sorting.reverse", true, "Reverse sort order") + pflag.String("grid.sorting.label", "alertname", "Label name to use when sorting alert grid by label") + pflag.Bool("log.config", true, "Log used configuration to log on startup") pflag.String("log.level", "info", "Log level, one of: debug, info, warning, error, fatal and panic") @@ -137,6 +142,9 @@ func (config *configSchema) Read() { config.Custom.JS = v.GetString("custom.js") config.Debug = v.GetBool("debug") config.Filters.Default = v.GetStringSlice("filters.default") + config.Grid.Sorting.Order = v.GetString("grid.sorting.order") + config.Grid.Sorting.Reverse = v.GetBool("grid.sorting.reverse") + config.Grid.Sorting.Label = v.GetString("grid.sorting.label") config.Labels.Color.Custom = map[string]map[string]string{} config.Labels.Color.Static = v.GetStringSlice("labels.color.static") config.Labels.Color.Unique = v.GetStringSlice("labels.color.unique") @@ -172,6 +180,10 @@ func (config *configSchema) Read() { log.Fatal(err) } + if !slices.StringInSlice([]string{"disabled", "startsAt", "label"}, config.Grid.Sorting.Order) { + log.Fatalf("Invalid grid.sorting.order value '%s', allowed options: disabled, startsAt, label", config.Grid.Sorting.Order) + } + // accept single Alertmanager server from flag/env if nothing is set yet if len(config.Alertmanager.Servers) == 0 && v.GetString("alertmanager.uri") != "" { log.Info("Using simple config with a single Alertmanager server") diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 034dfaf94..7900d7045 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -82,6 +82,11 @@ filters: default: - '@state=active' - foo=bar +grid: + sorting: + order: startsAt + reverse: true + label: alertname labels: keep: - foo diff --git a/internal/config/models.go b/internal/config/models.go index 2b3302555..f810796f6 100644 --- a/internal/config/models.go +++ b/internal/config/models.go @@ -43,6 +43,13 @@ type configSchema struct { Filters struct { Default []string } + Grid struct { + Sorting struct { + Order string + Reverse bool + Label string + } + } Labels struct { Keep []string Strip []string diff --git a/internal/models/api.go b/internal/models/api.go index 60ce14de8..fad016380 100644 --- a/internal/models/api.go +++ b/internal/models/api.go @@ -155,8 +155,16 @@ func (ag *APIAlertGroup) DedupSharedMaps() { } } +// GridSettings exposes all grid settings from the config file +type GridSettings struct { + Order string `json:"order"` + Reverse bool `json:"reverse"` + Label string `json:"label"` +} + // SortSettings nests all settings specific to sorting type SortSettings struct { + Grid GridSettings `json:"grid"` ValueMapping map[string]map[string]int `json:"valueMapping"` } diff --git a/views.go b/views.go index c54b5fdbd..d0838f8db 100644 --- a/views.go +++ b/views.go @@ -84,6 +84,11 @@ func alerts(c *gin.Context) { resp.Upstreams = getUpstreams() resp.Settings = models.Settings{ Sorting: models.SortSettings{ + Grid: models.GridSettings{ + Order: config.Config.Grid.Sorting.Order, + Reverse: config.Config.Grid.Sorting.Reverse, + Label: config.Config.Grid.Sorting.Label, + }, ValueMapping: map[string]map[string]int{}, }, StaticColorLabels: config.Config.Labels.Color.Static,