relabel: keep intermediate results in labels.Builder

Save work converting between Builder and Labels.

Also expose ProcessBuilder, so callers can supply a Builder.

Signed-off-by: Bryan Boreham <bjboreham@gmail.com>
This commit is contained in:
Bryan Boreham 2023-02-28 19:09:58 +00:00
parent d740abf0c6
commit 11d019ed5a

View file

@ -207,45 +207,52 @@ func (re Regexp) String() string {
// If a label set is dropped, EmptyLabels and false is returned. // If a label set is dropped, EmptyLabels and false is returned.
// May return the input labelSet modified. // May return the input labelSet modified.
func Process(lbls labels.Labels, cfgs ...*Config) (ret labels.Labels, keep bool) { func Process(lbls labels.Labels, cfgs ...*Config) (ret labels.Labels, keep bool) {
lb := labels.NewBuilder(labels.EmptyLabels()) lb := labels.NewBuilder(lbls)
for _, cfg := range cfgs { if !ProcessBuilder(lb, cfgs...) {
lbls, keep = relabel(lbls, cfg, lb) return labels.EmptyLabels(), false
if !keep {
return labels.EmptyLabels(), false
}
} }
return lbls, true return lb.Labels(lbls), true
} }
func relabel(lset labels.Labels, cfg *Config, lb *labels.Builder) (ret labels.Labels, keep bool) { // ProcessBuilder is like Process, but the caller passes a labels.Builder
// containing the initial set of labels, which is mutated by the rules.
func ProcessBuilder(lb *labels.Builder, cfgs ...*Config) (keep bool) {
for _, cfg := range cfgs {
keep = relabel(cfg, lb)
if !keep {
return false
}
}
return true
}
func relabel(cfg *Config, lb *labels.Builder) (keep bool) {
var va [16]string var va [16]string
values := va[:0] values := va[:0]
if len(cfg.SourceLabels) > cap(values) { if len(cfg.SourceLabels) > cap(values) {
values = make([]string, 0, len(cfg.SourceLabels)) values = make([]string, 0, len(cfg.SourceLabels))
} }
for _, ln := range cfg.SourceLabels { for _, ln := range cfg.SourceLabels {
values = append(values, lset.Get(string(ln))) values = append(values, lb.Get(string(ln)))
} }
val := strings.Join(values, cfg.Separator) val := strings.Join(values, cfg.Separator)
lb.Reset(lset)
switch cfg.Action { switch cfg.Action {
case Drop: case Drop:
if cfg.Regex.MatchString(val) { if cfg.Regex.MatchString(val) {
return labels.EmptyLabels(), false return false
} }
case Keep: case Keep:
if !cfg.Regex.MatchString(val) { if !cfg.Regex.MatchString(val) {
return labels.EmptyLabels(), false return false
} }
case DropEqual: case DropEqual:
if lset.Get(cfg.TargetLabel) == val { if lb.Get(cfg.TargetLabel) == val {
return labels.EmptyLabels(), false return false
} }
case KeepEqual: case KeepEqual:
if lset.Get(cfg.TargetLabel) != val { if lb.Get(cfg.TargetLabel) != val {
return labels.EmptyLabels(), false return false
} }
case Replace: case Replace:
indexes := cfg.Regex.FindStringSubmatchIndex(val) indexes := cfg.Regex.FindStringSubmatchIndex(val)
@ -274,20 +281,20 @@ func relabel(lset labels.Labels, cfg *Config, lb *labels.Builder) (ret labels.La
mod := binary.BigEndian.Uint64(hash[8:]) % cfg.Modulus mod := binary.BigEndian.Uint64(hash[8:]) % cfg.Modulus
lb.Set(cfg.TargetLabel, fmt.Sprintf("%d", mod)) lb.Set(cfg.TargetLabel, fmt.Sprintf("%d", mod))
case LabelMap: case LabelMap:
lset.Range(func(l labels.Label) { lb.Range(func(l labels.Label) {
if cfg.Regex.MatchString(l.Name) { if cfg.Regex.MatchString(l.Name) {
res := cfg.Regex.ReplaceAllString(l.Name, cfg.Replacement) res := cfg.Regex.ReplaceAllString(l.Name, cfg.Replacement)
lb.Set(res, l.Value) lb.Set(res, l.Value)
} }
}) })
case LabelDrop: case LabelDrop:
lset.Range(func(l labels.Label) { lb.Range(func(l labels.Label) {
if cfg.Regex.MatchString(l.Name) { if cfg.Regex.MatchString(l.Name) {
lb.Del(l.Name) lb.Del(l.Name)
} }
}) })
case LabelKeep: case LabelKeep:
lset.Range(func(l labels.Label) { lb.Range(func(l labels.Label) {
if !cfg.Regex.MatchString(l.Name) { if !cfg.Regex.MatchString(l.Name) {
lb.Del(l.Name) lb.Del(l.Name)
} }
@ -296,5 +303,5 @@ func relabel(lset labels.Labels, cfg *Config, lb *labels.Builder) (ret labels.La
panic(fmt.Errorf("relabel: unknown relabel action type %q", cfg.Action)) panic(fmt.Errorf("relabel: unknown relabel action type %q", cfg.Action))
} }
return lb.Labels(lset), true return true
} }