mirror of
https://github.com/prymitive/karma
synced 2026-08-23 11:56:20 +00:00
fix(backend): reduce allocations
This commit is contained in:
committed by
Łukasz Mierzwa
parent
492c564e74
commit
ccd14cbc7f
+3
-3
@@ -4,12 +4,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"slices"
|
||||
|
||||
"github.com/prymitive/karma/internal/alertmanager"
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/regex"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -114,7 +114,7 @@ type silenceACL struct {
|
||||
func (acl *silenceACL) isAllowed(amName string, silence *models.Silence, groups []string) (bool, error) {
|
||||
groupMatch := len(acl.Scope.Groups) == 0
|
||||
for _, aclGroup := range acl.Scope.Groups {
|
||||
if slices.StringInSlice(groups, aclGroup) {
|
||||
if slices.Contains(groups, aclGroup) {
|
||||
groupMatch = true
|
||||
break
|
||||
}
|
||||
@@ -172,7 +172,7 @@ func newSilenceACLFromConfig(cfg config.SilenceACLRule) (*silenceACL, error) {
|
||||
Matchers: aclMatchers{},
|
||||
}
|
||||
|
||||
if !slices.StringInSlice(allACLActions, acl.Action) {
|
||||
if !slices.Contains(allACLActions, acl.Action) {
|
||||
return nil, fmt.Errorf("silence ACL rule requires 'action' to be one of %v, got %q", allACLActions, acl.Action)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -24,7 +25,6 @@ import (
|
||||
"github.com/prymitive/karma/internal/alertmanager"
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/prymitive/karma/internal/mapper"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
uriUtil "github.com/prymitive/karma/internal/uri"
|
||||
)
|
||||
|
||||
@@ -338,7 +338,7 @@ func countAlerts(uri string, timeout time.Duration, transport http.RoundTripper,
|
||||
|
||||
lv := model.LabelSet{}
|
||||
for k, v := range labels {
|
||||
if slices.StringInSlice(names, k) {
|
||||
if slices.Contains(names, k) {
|
||||
lv[model.LabelName(k)] = model.LabelValue(v)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"slices"
|
||||
"sort"
|
||||
|
||||
"github.com/fvbommel/sortorder"
|
||||
@@ -12,7 +13,6 @@ import (
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/prymitive/karma/internal/filters"
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
"github.com/prymitive/karma/internal/uri"
|
||||
)
|
||||
|
||||
@@ -299,7 +299,7 @@ func autoGridLabel(dedupedAlerts []models.AlertGroup) string {
|
||||
|
||||
candidates := map[string]int{}
|
||||
for key, vals := range labelToAlertCount {
|
||||
if slices.StringInSlice(config.Config.Grid.Auto.Ignore, key) {
|
||||
if slices.Contains(config.Config.Grid.Auto.Ignore, key) {
|
||||
continue
|
||||
}
|
||||
var total int
|
||||
|
||||
+4
-4
@@ -3,11 +3,11 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/prymitive/karma/internal/regex"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
)
|
||||
|
||||
type authUserKey string
|
||||
@@ -15,7 +15,7 @@ type authUserKey string
|
||||
func userGroups(username string) []string {
|
||||
groups := []string{}
|
||||
for _, authGroup := range config.Config.Authorization.Groups {
|
||||
if slices.StringInSlice(authGroup.Members, username) {
|
||||
if slices.Contains(authGroup.Members, username) {
|
||||
groups = append(groups, authGroup.Name)
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ func groupsFromHeaders(r *http.Request, groupName, groupValueRegex, groupValueSe
|
||||
func headerAuth(name, valueRegex, groupName, groupValueRegex, groupValueSeparator string, allowBypass []string) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if slices.StringInSlice(allowBypass, r.URL.Path) {
|
||||
if slices.Contains(allowBypass, r.URL.Path) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
@@ -92,7 +92,7 @@ func getGroupsFromContext(r *http.Request) []string {
|
||||
func basicAuth(creds map[string]string, groupName, groupValueRegex, groupValueSeparator string, allowBypass []string) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if slices.StringInSlice(allowBypass, r.URL.Path) {
|
||||
if slices.Contains(allowBypass, r.URL.Path) {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
+10
-9
@@ -9,6 +9,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -21,7 +22,7 @@ import (
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/prymitive/karma/internal/filters"
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
sliceutils "github.com/prymitive/karma/internal/slices"
|
||||
"github.com/prymitive/karma/internal/transform"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -536,10 +537,10 @@ func labelsSettings(grids []models.APIGrid, store models.LabelsSettings) {
|
||||
|
||||
func labelSettings(name string, store models.LabelsSettings) {
|
||||
var isStatic, isValueOnly bool
|
||||
if slices.StringInSlice(config.Config.Labels.Color.Static, name) {
|
||||
if slices.Contains(config.Config.Labels.Color.Static, name) {
|
||||
isStatic = true
|
||||
}
|
||||
if slices.StringInSlice(config.Config.Labels.ValueOnly, name) || slices.MatchesAnyRegex(name, config.Config.Labels.CompiledValueOnlyRegex) {
|
||||
if slices.Contains(config.Config.Labels.ValueOnly, name) || sliceutils.MatchesAnyRegex(name, config.Config.Labels.CompiledValueOnlyRegex) {
|
||||
isValueOnly = true
|
||||
}
|
||||
if isStatic || isValueOnly {
|
||||
@@ -577,12 +578,12 @@ func autocomplete(w http.ResponseWriter, r *http.Request) {
|
||||
dedupedAutocomplete := alertmanager.DedupAutocomplete()
|
||||
|
||||
for _, hint := range dedupedAutocomplete {
|
||||
if strings.HasPrefix(strings.ToLower(hint.Value), strings.ToLower(term)) {
|
||||
acData = append(acData, hint.Value)
|
||||
if strings.HasPrefix(strings.ToLower(hint.Value.Value()), strings.ToLower(term)) {
|
||||
acData = append(acData, hint.Value.Value())
|
||||
} else {
|
||||
for _, token := range hint.Tokens {
|
||||
if strings.HasPrefix(strings.ToLower(token), strings.ToLower(term)) {
|
||||
acData = append(acData, hint.Value)
|
||||
if strings.HasPrefix(strings.ToLower(token.Value()), strings.ToLower(term)) {
|
||||
acData = append(acData, hint.Value.Value())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -630,7 +631,7 @@ func silences(w http.ResponseWriter, r *http.Request) {
|
||||
upstreams := getUpstreams()
|
||||
for _, u := range upstreams.Instances {
|
||||
if strings.ToLower(u.Name) == searchTerm || strings.ToLower(u.Cluster) == searchTerm {
|
||||
if !slices.StringInSlice(clusters, u.Cluster) {
|
||||
if !slices.Contains(clusters, u.Cluster) {
|
||||
clusters = append(clusters, strings.ToLower(u.Cluster))
|
||||
}
|
||||
}
|
||||
@@ -648,7 +649,7 @@ func silences(w http.ResponseWriter, r *http.Request) {
|
||||
isMatch = true
|
||||
case "@cluster="+strings.ToLower(silence.Cluster) == searchTerm:
|
||||
isMatch = true
|
||||
case slices.StringInSlice(clusters, strings.ToLower(silence.Cluster)):
|
||||
case slices.Contains(clusters, strings.ToLower(silence.Cluster)):
|
||||
isMatch = true
|
||||
case strings.Contains(strings.ToLower(silence.Silence.Comment), searchTerm):
|
||||
isMatch = true
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"regexp"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -25,7 +26,6 @@ import (
|
||||
"github.com/prymitive/karma/internal/mock"
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/regex"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
@@ -634,7 +634,7 @@ func TestValidateAllAlerts(t *testing.T) {
|
||||
}
|
||||
for _, ag := range ur.Grids[0].AlertGroups {
|
||||
for _, a := range ag.Alerts {
|
||||
if !slices.StringInSlice(models.AlertStateList, a.State) {
|
||||
if !slices.Contains(models.AlertStateList, a.State) {
|
||||
t.Errorf("Invalid alert status '%s', not in %v", a.State, models.AlertStateList)
|
||||
}
|
||||
if len(a.Alertmanager) == 0 {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package alertmanager
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"sort"
|
||||
"time"
|
||||
"unique"
|
||||
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
"github.com/prymitive/karma/internal/transform"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -104,9 +105,9 @@ func DedupAlerts() []models.AlertGroup {
|
||||
// in the list of states from all instances
|
||||
alertLFP := alert.LabelsFingerprint()
|
||||
switch {
|
||||
case slices.StringInSlice(alertStates[alertLFP], models.AlertStateActive):
|
||||
case slices.Contains(alertStates[alertLFP], models.AlertStateActive):
|
||||
alert.State = models.AlertStateActive
|
||||
case slices.StringInSlice(alertStates[alertLFP], models.AlertStateSuppressed):
|
||||
case slices.Contains(alertStates[alertLFP], models.AlertStateSuppressed):
|
||||
alert.State = models.AlertStateSuppressed
|
||||
default:
|
||||
alert.State = models.AlertStateUnprocessed
|
||||
@@ -187,7 +188,7 @@ func DedupColors() models.LabelsColorMap {
|
||||
// DedupAutocomplete returns a list of autocomplete hints merged from all
|
||||
// Alertmanager upstreams
|
||||
func DedupAutocomplete() []models.Autocomplete {
|
||||
uniqueAutocomplete := map[string]*models.Autocomplete{}
|
||||
uniqueAutocomplete := map[unique.Handle[string]]*models.Autocomplete{}
|
||||
|
||||
upstreams := GetAlertmanagers()
|
||||
|
||||
@@ -197,7 +198,7 @@ func DedupAutocomplete() []models.Autocomplete {
|
||||
h, found := uniqueAutocomplete[hint.Value]
|
||||
if found {
|
||||
for _, token := range hint.Tokens {
|
||||
if !slices.StringInSlice(h.Tokens, token) {
|
||||
if !slices.Contains(h.Tokens, token) {
|
||||
h.Tokens = append(h.Tokens, token)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
"unique"
|
||||
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/prymitive/karma/internal/filters"
|
||||
@@ -239,7 +240,7 @@ func (am *Alertmanager) pullAlerts(version string, si *intern.Interner) error {
|
||||
|
||||
dedupedGroups := make([]models.AlertGroup, 0, len(uniqueGroups))
|
||||
colors := models.LabelsColorMap{}
|
||||
autocompleteMap := map[string]*models.Autocomplete{}
|
||||
autocompleteMap := map[unique.Handle[string]]*models.Autocomplete{}
|
||||
|
||||
log.Info().
|
||||
Str("alertmanager", am.Name).
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prymitive/karma/internal/regex"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
"github.com/prymitive/karma/internal/uri"
|
||||
|
||||
"github.com/knadh/koanf"
|
||||
@@ -352,7 +352,7 @@ func (config *configSchema) Read(flags *pflag.FlagSet) (string, error) {
|
||||
config.Authentication.Enabled = true
|
||||
}
|
||||
|
||||
if !slices.StringInSlice([]string{"omit", "include", "same-origin"}, config.Alertmanager.CORS.Credentials) {
|
||||
if !slices.Contains([]string{"omit", "include", "same-origin"}, config.Alertmanager.CORS.Credentials) {
|
||||
return "", fmt.Errorf("invalid alertmanager.cors.credentials value '%s', allowed options: omit, inclue, same-origin", config.Alertmanager.CORS.Credentials)
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ func (config *configSchema) Read(flags *pflag.FlagSet) (string, error) {
|
||||
if s.CORS.Credentials == "" {
|
||||
config.Alertmanager.Servers[i].CORS.Credentials = config.Alertmanager.CORS.Credentials
|
||||
}
|
||||
if !slices.StringInSlice([]string{"omit", "include", "same-origin"}, config.Alertmanager.Servers[i].CORS.Credentials) {
|
||||
if !slices.Contains([]string{"omit", "include", "same-origin"}, config.Alertmanager.Servers[i].CORS.Credentials) {
|
||||
return "", fmt.Errorf("invalid cors.credentials value '%s' for alertmanager '%s', allowed options: omit, inclue, same-origin", config.Alertmanager.Servers[i].CORS.Credentials, s.Name)
|
||||
}
|
||||
}
|
||||
@@ -434,15 +434,15 @@ func (config *configSchema) Read(flags *pflag.FlagSet) (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if !slices.StringInSlice([]string{"disabled", "startsAt", "label"}, config.Grid.Sorting.Order) {
|
||||
if !slices.Contains([]string{"disabled", "startsAt", "label"}, config.Grid.Sorting.Order) {
|
||||
return "", fmt.Errorf("invalid grid.sorting.order value '%s', allowed options: disabled, startsAt, label", config.Grid.Sorting.Order)
|
||||
}
|
||||
|
||||
if !slices.StringInSlice([]string{"expanded", "collapsed", "collapsedOnMobile"}, config.UI.CollapseGroups) {
|
||||
if !slices.Contains([]string{"expanded", "collapsed", "collapsedOnMobile"}, config.UI.CollapseGroups) {
|
||||
return "", fmt.Errorf("invalid ui.collapseGroups value '%s', allowed options: expanded, collapsed, collapsedOnMobile", config.UI.CollapseGroups)
|
||||
}
|
||||
|
||||
if !slices.StringInSlice([]string{"light", "dark", "auto"}, config.UI.Theme) {
|
||||
if !slices.Contains([]string{"light", "dark", "auto"}, config.UI.Theme) {
|
||||
return "", fmt.Errorf("invalid ui.theme value '%s', allowed options: light, dark, auto", config.UI.Theme)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
package filters
|
||||
|
||||
import (
|
||||
"unique"
|
||||
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
)
|
||||
|
||||
type autocompleteFactory func(name string, operators []string, alerts []models.Alert) []models.Autocomplete
|
||||
|
||||
func makeAC(value string, tokens []string) models.Autocomplete {
|
||||
acHint := models.Autocomplete{
|
||||
Value: value,
|
||||
Tokens: tokens,
|
||||
uTokens := make([]unique.Handle[string], 0, len(tokens))
|
||||
for _, token := range tokens {
|
||||
uTokens = append(uTokens, unique.Make(token))
|
||||
}
|
||||
acHint.Tokens = append(acHint.Tokens, value)
|
||||
|
||||
acHint := models.Autocomplete{
|
||||
Value: unique.Make(value),
|
||||
Tokens: uTokens,
|
||||
}
|
||||
acHint.Tokens = append(acHint.Tokens, unique.Make(value))
|
||||
return acHint
|
||||
}
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ func TestBuildAutocomplete(t *testing.T) {
|
||||
for _, acTest := range acTests {
|
||||
result := []string{}
|
||||
for _, hint := range filters.BuildAutocomplete(acTest.Alerts) {
|
||||
result = append(result, hint.Value)
|
||||
result = append(result, hint.Value.Value())
|
||||
}
|
||||
|
||||
sort.Strings(result)
|
||||
|
||||
@@ -3,10 +3,10 @@ package filters
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
)
|
||||
|
||||
// FilterT provides methods for interacting with alert filters
|
||||
@@ -124,7 +124,7 @@ func NewFilter(expression string) FilterT {
|
||||
// filter name doesn't match, keep searching
|
||||
continue
|
||||
}
|
||||
if !slices.StringInSlice(fc.SupportedOperators, operator) {
|
||||
if !slices.Contains(fc.SupportedOperators, operator) {
|
||||
return &invalid
|
||||
}
|
||||
// we validate operator above, no need to re-check
|
||||
|
||||
@@ -2,10 +2,10 @@ package filters
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
)
|
||||
|
||||
type stateFilter struct {
|
||||
@@ -20,7 +20,7 @@ func (filter *stateFilter) init(name string, matcher *matcherT, rawText string,
|
||||
filter.RawText = rawText
|
||||
filter.IsValid = isValid
|
||||
filter.Value = value
|
||||
if !slices.StringInSlice(models.AlertStateList, value) {
|
||||
if !slices.Contains(models.AlertStateList, value) {
|
||||
filter.IsValid = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package filters_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"github.com/prymitive/karma/internal/alertmanager"
|
||||
"github.com/prymitive/karma/internal/filters"
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
@@ -903,7 +903,7 @@ func TestFilters(t *testing.T) {
|
||||
t.Errorf("[%s] GetIsValid() returned %#v while %#v was expected", ft.Expression, f.GetIsValid(), ft.IsValid)
|
||||
}
|
||||
if f.GetIsValid() {
|
||||
isAlertmanagerFilter := slices.StringInSlice(
|
||||
isAlertmanagerFilter := slices.Contains(
|
||||
[]string{"@age", "@alertmanager", "@cluster", "@inhibited", "@inhibited_by", "@state", "@silenced_by", "@silence_ticket", "@silence_author", "@fingerprint"},
|
||||
f.GetName())
|
||||
if isAlertmanagerFilter != f.GetIsAlertmanagerFilter() {
|
||||
|
||||
@@ -2,13 +2,13 @@ package models
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/fvbommel/sortorder"
|
||||
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
)
|
||||
|
||||
// Annotation extends Alertmanager scheme of key:value with additional data
|
||||
@@ -90,7 +90,7 @@ func isLink(s string) bool {
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if slices.StringInSlice(linkSchemes, u.Scheme) {
|
||||
if slices.Contains(linkSchemes, u.Scheme) {
|
||||
// parses with url.Parse and scheme is in the list of supported schemes
|
||||
return true
|
||||
}
|
||||
@@ -98,11 +98,11 @@ func isLink(s string) bool {
|
||||
}
|
||||
|
||||
func isVisible(name string) bool {
|
||||
if slices.StringInSlice(config.Config.Annotations.Visible, name) {
|
||||
if slices.Contains(config.Config.Annotations.Visible, name) {
|
||||
// annotation was explicitly marked as visible
|
||||
return true
|
||||
}
|
||||
if slices.StringInSlice(config.Config.Annotations.Hidden, name) {
|
||||
if slices.Contains(config.Config.Annotations.Hidden, name) {
|
||||
// annotation was explicitly marked as hidden
|
||||
return false
|
||||
}
|
||||
@@ -115,5 +115,5 @@ func isVisible(name string) bool {
|
||||
}
|
||||
|
||||
func isAction(name string) bool {
|
||||
return slices.StringInSlice(config.Config.Annotations.Actions, name)
|
||||
return slices.Contains(config.Config.Annotations.Actions, name)
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ package models
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"unique"
|
||||
|
||||
"github.com/fvbommel/sortorder"
|
||||
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
)
|
||||
|
||||
// Filter holds returned data on any filter passed by the user as part of the query
|
||||
@@ -153,7 +153,7 @@ func (ag *APIAlertGroup) dedupLabels() {
|
||||
func (ag *APIAlertGroup) removeGroupingLabels(dropNames []string) {
|
||||
newGroupLabels := Labels{}
|
||||
for _, l := range ag.Labels {
|
||||
if slices.StringInSlice(dropNames, l.Name) {
|
||||
if slices.Contains(dropNames, l.Name) {
|
||||
continue
|
||||
}
|
||||
newGroupLabels = newGroupLabels.Add(l)
|
||||
@@ -163,7 +163,7 @@ func (ag *APIAlertGroup) removeGroupingLabels(dropNames []string) {
|
||||
for i, alert := range ag.Alerts {
|
||||
newAlertLabels := Labels{}
|
||||
for _, l := range alert.Labels {
|
||||
if slices.StringInSlice(dropNames, l.Name) {
|
||||
if slices.Contains(dropNames, l.Name) {
|
||||
// skip all labels from the drop list
|
||||
continue
|
||||
}
|
||||
@@ -202,7 +202,7 @@ func (ag *APIAlertGroup) dedupAnnotations() {
|
||||
for _, annotation := range alert.Annotations {
|
||||
key := fmt.Sprintf("%s\n%s", annotation.Name, annotation.Value)
|
||||
if annotationCount[key] == totalAlerts {
|
||||
if !slices.StringInSlice(sharedKeys, key) {
|
||||
if !slices.Contains(sharedKeys, key) {
|
||||
sharedAnnotations = append(sharedAnnotations, annotation)
|
||||
sharedKeys = append(sharedKeys, key)
|
||||
}
|
||||
@@ -225,7 +225,7 @@ func (ag *APIAlertGroup) dedupSilences() {
|
||||
// process each cluster only once, rather than each alertmanager instance
|
||||
clusters := []string{}
|
||||
for _, am := range alert.Alertmanager {
|
||||
if slices.StringInSlice(clusters, am.Cluster) {
|
||||
if slices.Contains(clusters, am.Cluster) {
|
||||
continue
|
||||
}
|
||||
clusters = append(clusters, am.Cluster)
|
||||
@@ -349,7 +349,7 @@ func (ag *APIAlertGroup) populateAllLabels() {
|
||||
if _, ok := ag.AllLabels[alert.State][l.Name]; !ok {
|
||||
ag.AllLabels[alert.State][l.Name] = []string{}
|
||||
}
|
||||
if !slices.StringInSlice(ag.AllLabels[alert.State][l.Name], l.Value) {
|
||||
if !slices.Contains(ag.AllLabels[alert.State][l.Name], l.Value) {
|
||||
ag.AllLabels[alert.State][l.Name] = append(ag.AllLabels[alert.State][l.Name], l.Value)
|
||||
}
|
||||
}
|
||||
@@ -482,8 +482,8 @@ type AlertsResponse struct {
|
||||
// Autocomplete is the structure of autocomplete object for filter hints
|
||||
// this is internal representation, not what's returned to the user
|
||||
type Autocomplete struct {
|
||||
Value string `json:"value"`
|
||||
Tokens []string `json:"tokens"`
|
||||
Value unique.Handle[string] `json:"value"`
|
||||
Tokens []unique.Handle[string] `json:"tokens"`
|
||||
}
|
||||
|
||||
type Counters struct {
|
||||
|
||||
@@ -6,26 +6,6 @@ import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// BoolInSlice returns true if given bool is found in a slice of bools
|
||||
func BoolInSlice(boolArray []bool, value bool) bool {
|
||||
for _, s := range boolArray {
|
||||
if s == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// StringInSlice returns true if given string is found in a slice of strings
|
||||
func StringInSlice(stringArray []string, value string) bool {
|
||||
for _, s := range stringArray {
|
||||
if s == value {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// StringSliceToSHA1 returns a SHA1 hash computed from a slice of strings
|
||||
func StringSliceToSHA1(stringArray []string) (string, error) {
|
||||
h := sha1.New()
|
||||
|
||||
@@ -8,112 +8,6 @@ import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
type stringSliceTest struct {
|
||||
value string
|
||||
array []string
|
||||
found bool
|
||||
}
|
||||
|
||||
var stringSliceTests = []stringSliceTest{
|
||||
{
|
||||
array: []string{},
|
||||
value: "aa",
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "aa",
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "bb",
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "cc",
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "dd",
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "bbcc",
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "b",
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
array: []string{"aa", "bb", "cc", "dd"},
|
||||
value: "",
|
||||
found: false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestStringInSlice(t *testing.T) {
|
||||
for _, testCase := range stringSliceTests {
|
||||
found := slices.StringInSlice(testCase.array, testCase.value)
|
||||
if found != testCase.found {
|
||||
t.Errorf("Check if '%s' in slice %v returned %t, expected %t", testCase.value, testCase.array, found, testCase.found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type boolSliceTest struct {
|
||||
array []bool
|
||||
value bool
|
||||
found bool
|
||||
}
|
||||
|
||||
var boolSliceTests = []boolSliceTest{
|
||||
{
|
||||
array: []bool{},
|
||||
value: true,
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
array: []bool{},
|
||||
value: false,
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
array: []bool{true, false},
|
||||
value: true,
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
array: []bool{true, false},
|
||||
value: false,
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
array: []bool{false},
|
||||
value: true,
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
array: []bool{true},
|
||||
value: false,
|
||||
found: false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestBoolInSlice(t *testing.T) {
|
||||
for _, testCase := range boolSliceTests {
|
||||
found := slices.BoolInSlice(testCase.array, testCase.value)
|
||||
if found != testCase.found {
|
||||
t.Errorf("Check if '%t' in slice %v returned %t, expected %t", testCase.value, testCase.array, found, testCase.found)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringSliceToSHA1(t *testing.T) {
|
||||
s, err := slices.StringSliceToSHA1([]string{"a", "b", "c"})
|
||||
if err != nil {
|
||||
|
||||
@@ -5,10 +5,10 @@ import (
|
||||
"image/color"
|
||||
"io"
|
||||
"math/rand"
|
||||
"slices"
|
||||
|
||||
"github.com/prymitive/karma/internal/config"
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
|
||||
"github.com/prymitive/randomcolor"
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -84,7 +84,7 @@ func ColorLabel(colorStore models.LabelsColorMap, key, val string) {
|
||||
}
|
||||
|
||||
// if no custom color is found then generate unique colors if needed
|
||||
if slices.StringInSlice(config.Config.Labels.Color.Unique, key) {
|
||||
if slices.Contains(config.Config.Labels.Color.Unique, key) {
|
||||
if _, found := colorStore[key]; !found {
|
||||
colorStore[key] = make(map[string]models.LabelColors)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,12 @@ package transform
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
sliceutils "github.com/prymitive/karma/internal/slices"
|
||||
)
|
||||
|
||||
// StripLables allows filtering out some labels from alerts
|
||||
@@ -25,9 +26,9 @@ func StripLables(keptLabels, ignoredLabels []string, keptLabelsRegex, ignoredLab
|
||||
var inKeep, inStrip bool
|
||||
for _, label := range sourceLabels {
|
||||
// is explicitly marked to be kept
|
||||
inKeep = slices.StringInSlice(keptLabels, label.Name) || slices.MatchesAnyRegex(label.Name, keptLabelsRegex)
|
||||
inKeep = slices.Contains(keptLabels, label.Name) || sliceutils.MatchesAnyRegex(label.Name, keptLabelsRegex)
|
||||
// is explicitly marked to be stripped
|
||||
inStrip = slices.StringInSlice(ignoredLabels, label.Name) || slices.MatchesAnyRegex(label.Name, ignoredLabelsRegex)
|
||||
inStrip = slices.Contains(ignoredLabels, label.Name) || sliceutils.MatchesAnyRegex(label.Name, ignoredLabelsRegex)
|
||||
if (keepAll || inKeep) && !inStrip {
|
||||
l := models.Label{
|
||||
Name: label.Name,
|
||||
@@ -48,9 +49,9 @@ func StripReceivers(keptReceivers, ignoredReceivers []string, keptReceiversRegex
|
||||
// empty keep lists means keep everything by default
|
||||
keepAll := len(keptReceivers) == 0 && len(keptReceiversRegex) == 0
|
||||
// is explicitly marked to be kept
|
||||
inKeep := slices.StringInSlice(keptReceivers, alertReceiver) || slices.MatchesAnyRegex(alertReceiver, keptReceiversRegex)
|
||||
inKeep := slices.Contains(keptReceivers, alertReceiver) || sliceutils.MatchesAnyRegex(alertReceiver, keptReceiversRegex)
|
||||
// is explicitly marked to be stripped
|
||||
inStrip := slices.StringInSlice(ignoredReceivers, alertReceiver) || slices.MatchesAnyRegex(alertReceiver, ignoredReceiversRegex)
|
||||
inStrip := slices.Contains(ignoredReceivers, alertReceiver) || sliceutils.MatchesAnyRegex(alertReceiver, ignoredReceiversRegex)
|
||||
|
||||
if (keepAll || inKeep) && !inStrip {
|
||||
return false
|
||||
@@ -67,9 +68,9 @@ func StripAnnotations(keptAnnotations, ignoredAnnotations []string, sourceAnnota
|
||||
annotations := make(models.Annotations, 0, len(sourceAnnotations))
|
||||
for _, annotation := range sourceAnnotations {
|
||||
// is explicitly marked to be kept
|
||||
inKeep := slices.StringInSlice(keptAnnotations, annotation.Name)
|
||||
inKeep := slices.Contains(keptAnnotations, annotation.Name)
|
||||
// is explicitly marked to be stripped
|
||||
inStrip := slices.StringInSlice(ignoredAnnotations, annotation.Name)
|
||||
inStrip := slices.Contains(ignoredAnnotations, annotation.Name)
|
||||
if (keepAll || inKeep) && !inStrip {
|
||||
annotations = append(annotations, annotation)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user