cmd/amazon-cloudwatch-agent-target-allocator/prehook/relabel.go (74 lines of code) (raw):

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package prehook import ( "github.com/go-logr/logr" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/relabel" "github.com/aws/amazon-cloudwatch-agent-operator/cmd/amazon-cloudwatch-agent-target-allocator/target" ) type RelabelConfigTargetFilter struct { log logr.Logger relabelCfg map[string][]*relabel.Config } func NewRelabelConfigTargetFilter(log logr.Logger) Hook { return &RelabelConfigTargetFilter{ log: log, relabelCfg: make(map[string][]*relabel.Config), } } // helper function converts from model.LabelSet to []labels.Label. func convertLabelToPromLabelSet(lbls model.LabelSet) []labels.Label { newLabels := make([]labels.Label, len(lbls)) index := 0 for k, v := range lbls { newLabels[index].Name = string(k) newLabels[index].Value = string(v) index++ } return newLabels } func (tf *RelabelConfigTargetFilter) Apply(targets map[string]*target.Item) map[string]*target.Item { numTargets := len(targets) // need to wait until relabelCfg is set if len(tf.relabelCfg) == 0 { return targets } // Note: jobNameKey != tItem.JobName (jobNameKey is hashed) for jobNameKey, tItem := range targets { keepTarget := true lset := convertLabelToPromLabelSet(tItem.Labels) for _, cfg := range tf.relabelCfg[tItem.JobName] { if newLset, keep := relabel.Process(lset, cfg); !keep { keepTarget = false break // inner loop } else { lset = newLset } } if !keepTarget { delete(targets, jobNameKey) } } tf.log.V(2).Info("Filtering complete", "seen", numTargets, "kept", len(targets)) return targets } func (tf *RelabelConfigTargetFilter) SetConfig(cfgs map[string][]*relabel.Config) { relabelCfgCopy := make(map[string][]*relabel.Config) for key, val := range cfgs { relabelCfgCopy[key] = tf.replaceRelabelConfig(val) } tf.relabelCfg = relabelCfgCopy } // See this thread [https://github.com/open-telemetry/opentelemetry-operator/pull/1124/files#r983145795] // for why SHARD == 0 is a necessary substitution. Otherwise the keep action that uses this env variable, // would not match the regex and all targets end up dropped. Also note, $(SHARD) will always be 0 and it // does not make sense to read from the environment because it is never set in the allocator. func (tf *RelabelConfigTargetFilter) replaceRelabelConfig(cfg []*relabel.Config) []*relabel.Config { for i := range cfg { str := cfg[i].Regex.String() if str == "$(SHARD)" { cfg[i].Regex = relabel.MustNewRegexp("0") } } return cfg } func (tf *RelabelConfigTargetFilter) GetConfig() map[string][]*relabel.Config { relabelCfgCopy := make(map[string][]*relabel.Config) for k, v := range tf.relabelCfg { relabelCfgCopy[k] = v } return relabelCfgCopy }