From fbef0aeb5fdd6c3b6ca4338e3ee87f89a5c46601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Thu, 28 May 2020 13:48:33 +0100 Subject: [PATCH] fix(backend): reduce number of memory allocations --- cmd/karma/alerts.go | 5 +++-- internal/alertmanager/dedup.go | 16 +++++++++------- internal/alertmanager/models.go | 16 ++++++++-------- internal/alertmanager/upstream.go | 2 +- internal/filters/autocomplete.go | 2 +- internal/filters/filter_age.go | 2 +- internal/filters/filter_alertmanager.go | 2 +- internal/filters/filter_label.go | 2 +- internal/filters/filter_limit.go | 2 +- internal/filters/filter_receiver.go | 2 +- internal/filters/filter_silence_author.go | 2 +- internal/filters/filter_silence_id.go | 2 +- internal/filters/filter_silence_ticket.go | 2 +- internal/filters/filter_state.go | 2 +- internal/mapper/v017/api.go | 12 +++++++----- internal/models/annotation.go | 2 +- internal/models/api.go | 2 +- 17 files changed, 40 insertions(+), 35 deletions(-) diff --git a/cmd/karma/alerts.go b/cmd/karma/alerts.go index e78afc79d..f6c8ea52c 100644 --- a/cmd/karma/alerts.go +++ b/cmd/karma/alerts.go @@ -39,12 +39,13 @@ func countLabel(countStore map[string]map[string]int, key string, val string) { } func countersToLabelStats(counters map[string]map[string]int) models.LabelNameStatsList { - data := models.LabelNameStatsList{} + data := make(models.LabelNameStatsList, 0, len(counters)) for name, valueMap := range counters { + values := make(models.LabelValueStatsList, 0, len(valueMap)) nameStats := models.LabelNameStats{ Name: name, - Values: models.LabelValueStatsList{}, + Values: values, } for value, hits := range valueMap { diff --git a/internal/alertmanager/dedup.go b/internal/alertmanager/dedup.go index 8c9affa76..baf2b2fb4 100644 --- a/internal/alertmanager/dedup.go +++ b/internal/alertmanager/dedup.go @@ -20,7 +20,7 @@ func DedupAlerts() []models.AlertGroup { groups := am.Alerts() for _, ag := range groups { if _, found := uniqueGroups[ag.ID]; !found { - uniqueGroups[ag.ID] = []models.AlertGroup{} + uniqueGroups[ag.ID] = make([]models.AlertGroup, 0, len(groups)) } uniqueGroups[ag.ID] = append(uniqueGroups[ag.ID], ag) } @@ -66,7 +66,7 @@ func DedupAlerts() []models.AlertGroup { continue } ag := models.AlertGroup(agList[0]) - ag.Alerts = models.AlertList{} + ag.Alerts = make(models.AlertList, 0, len(alerts)) for _, alert := range alerts { alert := alert // scopelint pin // strip labels and annotations user doesn't want to see in the UI @@ -117,14 +117,16 @@ func DedupSilences() []models.ManagedSilence { now := time.Now() dedupedSilences := []models.ManagedSilence{} for cluster, silenceMap := range silenceByCluster { + s := make([]models.ManagedSilence, 0, len(silenceMap)) for _, silence := range silenceMap { managedSilence := models.ManagedSilence{ Cluster: cluster, IsExpired: silence.EndsAt.Before(now), Silence: silence, } - dedupedSilences = append(dedupedSilences, managedSilence) + s = append(s, managedSilence) } + dedupedSilences = append(dedupedSilences, s...) } return dedupedSilences } @@ -141,7 +143,7 @@ func DedupColors() models.LabelsColorMap { // map[string]map[string]LabelColors for labelName, valueMap := range colors { if _, found := dedupedColors[labelName]; !found { - dedupedColors[labelName] = map[string]models.LabelColors{} + dedupedColors[labelName] = make(map[string]models.LabelColors, len(valueMap)) } for labelVal, labelColors := range valueMap { if _, found := dedupedColors[labelName][labelVal]; !found { @@ -157,7 +159,6 @@ func DedupColors() models.LabelsColorMap { // DedupAutocomplete returns a list of autocomplete hints merged from all // Alertmanager upstreams func DedupAutocomplete() []models.Autocomplete { - dedupedAutocomplete := []models.Autocomplete{} uniqueAutocomplete := map[string]*models.Autocomplete{} upstreams := GetAlertmanagers() @@ -181,6 +182,7 @@ func DedupAutocomplete() []models.Autocomplete { } } + dedupedAutocomplete := make([]models.Autocomplete, 0, len(uniqueAutocomplete)) for _, hint := range uniqueAutocomplete { dedupedAutocomplete = append(dedupedAutocomplete, *hint) } @@ -199,7 +201,7 @@ func DedupKnownLabels() []string { } } - flatLabels := []string{} + flatLabels := make([]string, 0, len(dedupedLabels)) for key := range dedupedLabels { flatLabels = append(flatLabels, key) } @@ -221,7 +223,7 @@ func DedupKnownLabelValues(name string) []string { } } - flatValues := []string{} + flatValues := make([]string, 0, len(dedupedValues)) for key := range dedupedValues { flatValues = append(flatValues, key) } diff --git a/internal/alertmanager/models.go b/internal/alertmanager/models.go index 8cc573fce..95371a831 100644 --- a/internal/alertmanager/models.go +++ b/internal/alertmanager/models.go @@ -139,7 +139,7 @@ func (am *Alertmanager) pullSilences(version string) error { log.Infof("[%s] Got %d silences(s) in %s", am.Name, len(silences), time.Since(start)) log.Infof("[%s] Detecting ticket links in silences (%d)", am.Name, len(silences)) - silenceMap := map[string]models.Silence{} + silenceMap := make(map[string]models.Silence, len(silences)) for _, silence := range silences { silence := silence // scopelint pin silence.TicketID, silence.TicketURL = transform.DetectLinks(&silence) @@ -226,13 +226,13 @@ func (am *Alertmanager) pullAlerts(version string) error { } - dedupedGroups := []models.AlertGroup{} + dedupedGroups := make([]models.AlertGroup, 0, len(uniqueGroups)) colors := models.LabelsColorMap{} autocompleteMap := map[string]models.Autocomplete{} log.Infof("[%s] Processing unique alert groups (%d)", am.Name, len(uniqueGroups)) for _, ag := range uniqueGroups { - alerts := models.AlertList{} + alerts := make(models.AlertList, 0, len(uniqueAlerts[ag.ID])) for _, alert := range uniqueAlerts[ag.ID] { silences := map[string]*models.Silence{} @@ -282,12 +282,12 @@ func (am *Alertmanager) pullAlerts(version string) error { } log.Infof("[%s] Merging autocomplete data (%d)", am.Name, len(autocompleteMap)) - autocomplete := []models.Autocomplete{} + autocomplete := make([]models.Autocomplete, 0, len(autocompleteMap)) for _, hint := range autocompleteMap { autocomplete = append(autocomplete, hint) } - knownLabels := []string{} + knownLabels := make([]string, 0, len(knownLabelsMap)) for key := range knownLabelsMap { knownLabels = append(knownLabels, key) } @@ -355,7 +355,7 @@ func (am *Alertmanager) Silences() map[string]models.Silence { am.lock.RLock() defer am.lock.RUnlock() - silences := map[string]models.Silence{} + silences := make(map[string]models.Silence, len(am.silences)) for id, silence := range am.silences { silences[id] = silence } @@ -379,9 +379,9 @@ func (am *Alertmanager) Colors() models.LabelsColorMap { am.lock.RLock() defer am.lock.RUnlock() - colors := models.LabelsColorMap{} + colors := make(models.LabelsColorMap, len(am.colors)) for k, v := range am.colors { - colors[k] = map[string]models.LabelColors{} + colors[k] = make(map[string]models.LabelColors, len(v)) for nk, nv := range v { colors[k][nk] = nv } diff --git a/internal/alertmanager/upstream.go b/internal/alertmanager/upstream.go index 36272c30e..141daff6f 100644 --- a/internal/alertmanager/upstream.go +++ b/internal/alertmanager/upstream.go @@ -84,7 +84,7 @@ func RegisterAlertmanager(am *Alertmanager) error { // GetAlertmanagers returns a list of all defined Alertmanager instances func GetAlertmanagers() []*Alertmanager { - ams := []*Alertmanager{} + ams := make([]*Alertmanager, 0, len(upstreams)) for _, am := range upstreams { ams = append(ams, am) } diff --git a/internal/filters/autocomplete.go b/internal/filters/autocomplete.go index c4c2097aa..415bdec5e 100644 --- a/internal/filters/autocomplete.go +++ b/internal/filters/autocomplete.go @@ -26,7 +26,7 @@ func BuildAutocomplete(alerts []models.Alert) []models.Autocomplete { } } } - acHintsSlice := []models.Autocomplete{} + acHintsSlice := make([]models.Autocomplete, 0, len(acHints)) for _, hint := range acHints { acHintsSlice = append(acHintsSlice, hint) } diff --git a/internal/filters/filter_age.go b/internal/filters/filter_age.go index d8c59715b..40d17d60a 100644 --- a/internal/filters/filter_age.go +++ b/internal/filters/filter_age.go @@ -50,7 +50,7 @@ func newAgeFilter() FilterT { } func ageAutocomplete(name string, operators []string, alerts []models.Alert) []models.Autocomplete { - tokens := []models.Autocomplete{} + tokens := make([]models.Autocomplete, 0, len(operators)*2) for _, operator := range operators { tokens = append(tokens, makeAC( fmt.Sprintf("%s%s10m", name, operator), diff --git a/internal/filters/filter_alertmanager.go b/internal/filters/filter_alertmanager.go index 3d9430bf0..8d38fe669 100644 --- a/internal/filters/filter_alertmanager.go +++ b/internal/filters/filter_alertmanager.go @@ -53,7 +53,7 @@ func alertmanagerInstanceAutocomplete(name string, operators []string, alerts [] } } } - acData := []models.Autocomplete{} + acData := make([]models.Autocomplete, 0, len(tokens)) for _, token := range tokens { acData = append(acData, token) } diff --git a/internal/filters/filter_label.go b/internal/filters/filter_label.go index c957c7aa6..d0429431d 100644 --- a/internal/filters/filter_label.go +++ b/internal/filters/filter_label.go @@ -77,7 +77,7 @@ func labelAutocomplete(name string, operators []string, alerts []models.Alert) [ } } } - acData := []models.Autocomplete{} + acData := make([]models.Autocomplete, 0, len(tokens)) for _, token := range tokens { acData = append(acData, token) } diff --git a/internal/filters/filter_limit.go b/internal/filters/filter_limit.go index 0e82642d9..43b20fe5a 100644 --- a/internal/filters/filter_limit.go +++ b/internal/filters/filter_limit.go @@ -47,7 +47,7 @@ func newLimitFilter() FilterT { } func limitAutocomplete(name string, operators []string, alerts []models.Alert) []models.Autocomplete { - tokens := []models.Autocomplete{} + tokens := make([]models.Autocomplete, 0, len(operators)*2) for _, operator := range operators { tokens = append(tokens, makeAC( fmt.Sprintf("%s%s10", name, operator), diff --git a/internal/filters/filter_receiver.go b/internal/filters/filter_receiver.go index b44fbaa05..4d291fcd2 100644 --- a/internal/filters/filter_receiver.go +++ b/internal/filters/filter_receiver.go @@ -64,7 +64,7 @@ func receiverAutocomplete(name string, operators []string, alerts []models.Alert } } } - acData := []models.Autocomplete{} + acData := make([]models.Autocomplete, 0, len(tokens)) for _, token := range tokens { acData = append(acData, token) } diff --git a/internal/filters/filter_silence_author.go b/internal/filters/filter_silence_author.go index 0ae7f6dd3..cd5d2e93b 100644 --- a/internal/filters/filter_silence_author.go +++ b/internal/filters/filter_silence_author.go @@ -65,7 +65,7 @@ func silenceAuthorAutocomplete(name string, operators []string, alerts []models. } } } - acData := []models.Autocomplete{} + acData := make([]models.Autocomplete, 0, len(tokens)) for _, token := range tokens { acData = append(acData, token) } diff --git a/internal/filters/filter_silence_id.go b/internal/filters/filter_silence_id.go index 2c8b037b3..7ffe68c27 100644 --- a/internal/filters/filter_silence_id.go +++ b/internal/filters/filter_silence_id.go @@ -55,7 +55,7 @@ func silenceIDAutocomplete(name string, operators []string, alerts []models.Aler } } } - acData := []models.Autocomplete{} + acData := make([]models.Autocomplete, 0, len(tokens)) for _, token := range tokens { acData = append(acData, token) } diff --git a/internal/filters/filter_silence_ticket.go b/internal/filters/filter_silence_ticket.go index 99504dac0..0cfa6fa68 100644 --- a/internal/filters/filter_silence_ticket.go +++ b/internal/filters/filter_silence_ticket.go @@ -65,7 +65,7 @@ func silenceTicketIDAutocomplete(name string, operators []string, alerts []model } } } - acData := []models.Autocomplete{} + acData := make([]models.Autocomplete, 0, len(tokens)) for _, token := range tokens { acData = append(acData, token) } diff --git a/internal/filters/filter_state.go b/internal/filters/filter_state.go index f233a5592..95c08a1b9 100644 --- a/internal/filters/filter_state.go +++ b/internal/filters/filter_state.go @@ -43,7 +43,7 @@ func newStateFilter() FilterT { } func stateAutocomplete(name string, operators []string, alerts []models.Alert) []models.Autocomplete { - tokens := []models.Autocomplete{} + tokens := make([]models.Autocomplete, 0, len(operators)) for _, operator := range operators { for _, alert := range alerts { tokens = append(tokens, makeAC( diff --git a/internal/mapper/v017/api.go b/internal/mapper/v017/api.go index a6e358969..8faa7a041 100644 --- a/internal/mapper/v017/api.go +++ b/internal/mapper/v017/api.go @@ -41,16 +41,18 @@ func newClient(uri string, headers map[string]string, httpTransport http.RoundTr // Alerts will fetch all alert groups from the API func groups(c *client.Alertmanager, timeout time.Duration) ([]models.AlertGroup, error) { - ret := []models.AlertGroup{} - groups, err := c.Alertgroup.GetAlertGroups(alertgroup.NewGetAlertGroupsParamsWithTimeout(timeout)) if err != nil { return []models.AlertGroup{}, err } + + ret := make([]models.AlertGroup, 0, len(groups.Payload)) + for _, group := range groups.Payload { g := models.AlertGroup{ Receiver: *group.Receiver.Name, Labels: group.Labels, + Alerts: make(models.AlertList, 0, len(group.Alerts)), } for _, alert := range group.Alerts { a := models.Alert{ @@ -75,13 +77,13 @@ func groups(c *client.Alertmanager, timeout time.Duration) ([]models.AlertGroup, } func silences(c *client.Alertmanager, timeout time.Duration) ([]models.Silence, error) { - ret := []models.Silence{} - silences, err := c.Silence.GetSilences(silence.NewGetSilencesParamsWithTimeout(timeout)) if err != nil { - return ret, err + return []models.Silence{}, err } + ret := make([]models.Silence, 0, len(silences.Payload)) + for _, s := range silences.Payload { us := models.Silence{ ID: *s.ID, diff --git a/internal/models/annotation.go b/internal/models/annotation.go index 369586f38..b7b60c53b 100644 --- a/internal/models/annotation.go +++ b/internal/models/annotation.go @@ -55,7 +55,7 @@ func (a Annotations) Less(i, j int) bool { // AnnotationsFromMap will convert a map[string]string to a list of Annotation // instances, it takes care of setting proper value for Visible attribute func AnnotationsFromMap(m map[string]string) Annotations { - annotations := Annotations{} + annotations := make(Annotations, 0, len(m)) for name, value := range m { a := Annotation{ Name: name, diff --git a/internal/models/api.go b/internal/models/api.go index a8eca25ce..3ed26bfb6 100644 --- a/internal/models/api.go +++ b/internal/models/api.go @@ -104,7 +104,7 @@ type APIAlertGroup struct { func (ag *APIAlertGroup) dedupLabels() { totalAlerts := len(ag.Alerts) - labelCounts := map[string]int{} + labelCounts := make(map[string]int, len(ag.Alerts)) for _, alert := range ag.Alerts { for name, val := range alert.Labels {