mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
lib/promrelabel: add more optimizations for relabeling for common cases
This commit is contained in:
parent
dd1e53b119
commit
d136081040
12 changed files with 751 additions and 725 deletions
|
@ -41,7 +41,7 @@ func loadRelabelConfigs() (*relabelConfigs, error) {
|
|||
return nil, fmt.Errorf("too many -remoteWrite.urlRelabelConfig args: %d; it mustn't exceed the number of -remoteWrite.url args: %d",
|
||||
len(*relabelConfigPaths), len(*remoteWriteURLs))
|
||||
}
|
||||
rcs.perURL = make([][]promrelabel.ParsedRelabelConfig, len(*remoteWriteURLs))
|
||||
rcs.perURL = make([]*promrelabel.ParsedConfigs, len(*remoteWriteURLs))
|
||||
for i, path := range *relabelConfigPaths {
|
||||
if len(path) == 0 {
|
||||
// Skip empty relabel config.
|
||||
|
@ -57,8 +57,8 @@ func loadRelabelConfigs() (*relabelConfigs, error) {
|
|||
}
|
||||
|
||||
type relabelConfigs struct {
|
||||
global []promrelabel.ParsedRelabelConfig
|
||||
perURL [][]promrelabel.ParsedRelabelConfig
|
||||
global *promrelabel.ParsedConfigs
|
||||
perURL []*promrelabel.ParsedConfigs
|
||||
}
|
||||
|
||||
// initLabelsGlobal must be called after parsing command-line flags.
|
||||
|
@ -79,8 +79,8 @@ func initLabelsGlobal() {
|
|||
}
|
||||
}
|
||||
|
||||
func (rctx *relabelCtx) applyRelabeling(tss []prompbmarshal.TimeSeries, extraLabels []prompbmarshal.Label, prcs []promrelabel.ParsedRelabelConfig) []prompbmarshal.TimeSeries {
|
||||
if len(extraLabels) == 0 && len(prcs) == 0 {
|
||||
func (rctx *relabelCtx) applyRelabeling(tss []prompbmarshal.TimeSeries, extraLabels []prompbmarshal.Label, pcs *promrelabel.ParsedConfigs) []prompbmarshal.TimeSeries {
|
||||
if len(extraLabels) == 0 && pcs.Len() == 0 {
|
||||
// Nothing to change.
|
||||
return tss
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func (rctx *relabelCtx) applyRelabeling(tss []prompbmarshal.TimeSeries, extraLab
|
|||
labels = append(labels, *extraLabel)
|
||||
}
|
||||
}
|
||||
labels = promrelabel.ApplyRelabelConfigs(labels, labelsLen, prcs, true)
|
||||
labels = pcs.Apply(labels, labelsLen, true)
|
||||
if len(labels) == labelsLen {
|
||||
// Drop the current time series, since relabeling removed all the labels.
|
||||
continue
|
||||
|
|
|
@ -142,8 +142,8 @@ func Stop() {
|
|||
func Push(wr *prompbmarshal.WriteRequest) {
|
||||
var rctx *relabelCtx
|
||||
rcs := allRelabelConfigs.Load().(*relabelConfigs)
|
||||
prcsGlobal := rcs.global
|
||||
if len(prcsGlobal) > 0 || len(labelsGlobal) > 0 {
|
||||
pcsGlobal := rcs.global
|
||||
if pcsGlobal.Len() > 0 || len(labelsGlobal) > 0 {
|
||||
rctx = getRelabelCtx()
|
||||
}
|
||||
tss := wr.Timeseries
|
||||
|
@ -167,7 +167,7 @@ func Push(wr *prompbmarshal.WriteRequest) {
|
|||
}
|
||||
if rctx != nil {
|
||||
tssBlockLen := len(tssBlock)
|
||||
tssBlock = rctx.applyRelabeling(tssBlock, labelsGlobal, prcsGlobal)
|
||||
tssBlock = rctx.applyRelabeling(tssBlock, labelsGlobal, pcsGlobal)
|
||||
globalRelabelMetricsDropped.Add(tssBlockLen - len(tssBlock))
|
||||
}
|
||||
for _, rwctx := range rwctxs {
|
||||
|
@ -240,8 +240,8 @@ func (rwctx *remoteWriteCtx) Push(tss []prompbmarshal.TimeSeries) {
|
|||
var rctx *relabelCtx
|
||||
var v *[]prompbmarshal.TimeSeries
|
||||
rcs := allRelabelConfigs.Load().(*relabelConfigs)
|
||||
prcs := rcs.perURL[rwctx.idx]
|
||||
if len(prcs) > 0 {
|
||||
pcs := rcs.perURL[rwctx.idx]
|
||||
if pcs.Len() > 0 {
|
||||
rctx = getRelabelCtx()
|
||||
// Make a copy of tss before applying relabeling in order to prevent
|
||||
// from affecting time series for other remoteWrite.url configs.
|
||||
|
@ -250,7 +250,7 @@ func (rwctx *remoteWriteCtx) Push(tss []prompbmarshal.TimeSeries) {
|
|||
v = tssRelabelPool.Get().(*[]prompbmarshal.TimeSeries)
|
||||
tss = append(*v, tss...)
|
||||
tssLen := len(tss)
|
||||
tss = rctx.applyRelabeling(tss, nil, prcs)
|
||||
tss = rctx.applyRelabeling(tss, nil, pcs)
|
||||
rwctx.relabelMetricsDropped.Add(tssLen - len(tss))
|
||||
}
|
||||
pss := rwctx.pss
|
||||
|
|
|
@ -19,11 +19,11 @@ var relabelConfig = flag.String("relabelConfig", "", "Optional path to a file wi
|
|||
|
||||
// Init must be called after flag.Parse and before using the relabel package.
|
||||
func Init() {
|
||||
prcs, err := loadRelabelConfig()
|
||||
pcs, err := loadRelabelConfig()
|
||||
if err != nil {
|
||||
logger.Fatalf("cannot load relabelConfig: %s", err)
|
||||
}
|
||||
prcsGlobal.Store(&prcs)
|
||||
pcsGlobal.Store(pcs)
|
||||
if len(*relabelConfig) == 0 {
|
||||
return
|
||||
}
|
||||
|
@ -31,34 +31,34 @@ func Init() {
|
|||
go func() {
|
||||
for range sighupCh {
|
||||
logger.Infof("received SIGHUP; reloading -relabelConfig=%q...", *relabelConfig)
|
||||
prcs, err := loadRelabelConfig()
|
||||
pcs, err := loadRelabelConfig()
|
||||
if err != nil {
|
||||
logger.Errorf("cannot load the updated relabelConfig: %s; preserving the previous config", err)
|
||||
continue
|
||||
}
|
||||
prcsGlobal.Store(&prcs)
|
||||
pcsGlobal.Store(pcs)
|
||||
logger.Infof("successfully reloaded -relabelConfig=%q", *relabelConfig)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
var prcsGlobal atomic.Value
|
||||
var pcsGlobal atomic.Value
|
||||
|
||||
func loadRelabelConfig() ([]promrelabel.ParsedRelabelConfig, error) {
|
||||
func loadRelabelConfig() (*promrelabel.ParsedConfigs, error) {
|
||||
if len(*relabelConfig) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
prcs, err := promrelabel.LoadRelabelConfigs(*relabelConfig)
|
||||
pcs, err := promrelabel.LoadRelabelConfigs(*relabelConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error when reading -relabelConfig=%q: %w", *relabelConfig, err)
|
||||
}
|
||||
return prcs, nil
|
||||
return pcs, nil
|
||||
}
|
||||
|
||||
// HasRelabeling returns true if there is global relabeling.
|
||||
func HasRelabeling() bool {
|
||||
prcs := prcsGlobal.Load().(*[]promrelabel.ParsedRelabelConfig)
|
||||
return len(*prcs) > 0
|
||||
pcs := pcsGlobal.Load().(*promrelabel.ParsedConfigs)
|
||||
return pcs.Len() > 0
|
||||
}
|
||||
|
||||
// Ctx holds relabeling context.
|
||||
|
@ -77,8 +77,8 @@ func (ctx *Ctx) Reset() {
|
|||
//
|
||||
// The returned labels are valid until the next call to ApplyRelabeling.
|
||||
func (ctx *Ctx) ApplyRelabeling(labels []prompb.Label) []prompb.Label {
|
||||
prcs := prcsGlobal.Load().(*[]promrelabel.ParsedRelabelConfig)
|
||||
if len(*prcs) == 0 {
|
||||
pcs := pcsGlobal.Load().(*promrelabel.ParsedConfigs)
|
||||
if pcs.Len() == 0 {
|
||||
// There are no relabeling rules.
|
||||
return labels
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ func (ctx *Ctx) ApplyRelabeling(labels []prompb.Label) []prompb.Label {
|
|||
}
|
||||
|
||||
// Apply relabeling
|
||||
tmpLabels = promrelabel.ApplyRelabelConfigs(tmpLabels, 0, *prcs, true)
|
||||
tmpLabels = pcs.Apply(tmpLabels, 0, true)
|
||||
ctx.tmpLabels = tmpLabels
|
||||
if len(tmpLabels) == 0 {
|
||||
metricsDropped.Inc()
|
||||
|
|
|
@ -23,38 +23,78 @@ type RelabelConfig struct {
|
|||
Action string `yaml:"action,omitempty"`
|
||||
}
|
||||
|
||||
// ParsedConfigs represents parsed relabel configs.
|
||||
type ParsedConfigs struct {
|
||||
prcs []*parsedRelabelConfig
|
||||
}
|
||||
|
||||
// Len returns the number of relabel configs in pcs.
|
||||
func (pcs *ParsedConfigs) Len() int {
|
||||
if pcs == nil {
|
||||
return 0
|
||||
}
|
||||
return len(pcs.prcs)
|
||||
}
|
||||
|
||||
// String returns human-readabale representation for pcs.
|
||||
func (pcs *ParsedConfigs) String() string {
|
||||
if pcs == nil {
|
||||
return ""
|
||||
}
|
||||
var sb strings.Builder
|
||||
for _, prc := range pcs.prcs {
|
||||
fmt.Fprintf(&sb, "%s", prc.String())
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// LoadRelabelConfigs loads relabel configs from the given path.
|
||||
func LoadRelabelConfigs(path string) ([]ParsedRelabelConfig, error) {
|
||||
func LoadRelabelConfigs(path string) (*ParsedConfigs, error) {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot read `relabel_configs` from %q: %w", path, err)
|
||||
}
|
||||
data = envtemplate.Replace(data)
|
||||
var rcs []RelabelConfig
|
||||
if err := yaml.UnmarshalStrict(data, &rcs); err != nil {
|
||||
pcs, err := ParseRelabelConfigsData(data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot unmarshal `relabel_configs` from %q: %w", path, err)
|
||||
}
|
||||
return ParseRelabelConfigs(nil, rcs)
|
||||
return pcs, nil
|
||||
}
|
||||
|
||||
// ParseRelabelConfigsData parses relabel configs from the given data.
|
||||
func ParseRelabelConfigsData(data []byte) (*ParsedConfigs, error) {
|
||||
var rcs []RelabelConfig
|
||||
if err := yaml.UnmarshalStrict(data, &rcs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ParseRelabelConfigs(rcs)
|
||||
}
|
||||
|
||||
// ParseRelabelConfigs parses rcs to dst.
|
||||
func ParseRelabelConfigs(dst []ParsedRelabelConfig, rcs []RelabelConfig) ([]ParsedRelabelConfig, error) {
|
||||
func ParseRelabelConfigs(rcs []RelabelConfig) (*ParsedConfigs, error) {
|
||||
if len(rcs) == 0 {
|
||||
return dst, nil
|
||||
return nil, nil
|
||||
}
|
||||
prcs := make([]*parsedRelabelConfig, len(rcs))
|
||||
for i := range rcs {
|
||||
var err error
|
||||
dst, err = parseRelabelConfig(dst, &rcs[i])
|
||||
prc, err := parseRelabelConfig(&rcs[i])
|
||||
if err != nil {
|
||||
return dst, fmt.Errorf("error when parsing `relabel_config` #%d: %w", i+1, err)
|
||||
return nil, fmt.Errorf("error when parsing `relabel_config` #%d: %w", i+1, err)
|
||||
}
|
||||
prcs[i] = prc
|
||||
}
|
||||
return dst, nil
|
||||
return &ParsedConfigs{
|
||||
prcs: prcs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
var defaultRegexForRelabelConfig = regexp.MustCompile("^(.*)$")
|
||||
var (
|
||||
defaultOriginalRegexForRelabelConfig = regexp.MustCompile(".*")
|
||||
defaultRegexForRelabelConfig = regexp.MustCompile("^(.*)$")
|
||||
)
|
||||
|
||||
func parseRelabelConfig(dst []ParsedRelabelConfig, rc *RelabelConfig) ([]ParsedRelabelConfig, error) {
|
||||
func parseRelabelConfig(rc *RelabelConfig) (*parsedRelabelConfig, error) {
|
||||
sourceLabels := rc.SourceLabels
|
||||
separator := ";"
|
||||
if rc.Separator != nil {
|
||||
|
@ -62,6 +102,7 @@ func parseRelabelConfig(dst []ParsedRelabelConfig, rc *RelabelConfig) ([]ParsedR
|
|||
}
|
||||
targetLabel := rc.TargetLabel
|
||||
regexCompiled := defaultRegexForRelabelConfig
|
||||
regexOriginalCompiled := defaultOriginalRegexForRelabelConfig
|
||||
if rc.Regex != nil {
|
||||
regex := *rc.Regex
|
||||
if rc.Action != "replace_all" && rc.Action != "labelmap_all" {
|
||||
|
@ -69,9 +110,14 @@ func parseRelabelConfig(dst []ParsedRelabelConfig, rc *RelabelConfig) ([]ParsedR
|
|||
}
|
||||
re, err := regexp.Compile(regex)
|
||||
if err != nil {
|
||||
return dst, fmt.Errorf("cannot parse `regex` %q: %w", regex, err)
|
||||
return nil, fmt.Errorf("cannot parse `regex` %q: %w", regex, err)
|
||||
}
|
||||
regexCompiled = re
|
||||
reOriginal, err := regexp.Compile(*rc.Regex)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse `regex` %q: %w", *rc.Regex, err)
|
||||
}
|
||||
regexOriginalCompiled = reOriginal
|
||||
}
|
||||
modulus := rc.Modulus
|
||||
replacement := "$1"
|
||||
|
@ -85,49 +131,49 @@ func parseRelabelConfig(dst []ParsedRelabelConfig, rc *RelabelConfig) ([]ParsedR
|
|||
switch action {
|
||||
case "replace":
|
||||
if targetLabel == "" {
|
||||
return dst, fmt.Errorf("missing `target_label` for `action=replace`")
|
||||
return nil, fmt.Errorf("missing `target_label` for `action=replace`")
|
||||
}
|
||||
case "replace_all":
|
||||
if len(sourceLabels) == 0 {
|
||||
return dst, fmt.Errorf("missing `source_labels` for `action=replace_all`")
|
||||
return nil, fmt.Errorf("missing `source_labels` for `action=replace_all`")
|
||||
}
|
||||
if targetLabel == "" {
|
||||
return dst, fmt.Errorf("missing `target_label` for `action=replace_all`")
|
||||
return nil, fmt.Errorf("missing `target_label` for `action=replace_all`")
|
||||
}
|
||||
case "keep_if_equal":
|
||||
if len(sourceLabels) < 2 {
|
||||
return dst, fmt.Errorf("`source_labels` must contain at least two entries for `action=keep_if_equal`; got %q", sourceLabels)
|
||||
return nil, fmt.Errorf("`source_labels` must contain at least two entries for `action=keep_if_equal`; got %q", sourceLabels)
|
||||
}
|
||||
case "drop_if_equal":
|
||||
if len(sourceLabels) < 2 {
|
||||
return dst, fmt.Errorf("`source_labels` must contain at least two entries for `action=drop_if_equal`; got %q", sourceLabels)
|
||||
return nil, fmt.Errorf("`source_labels` must contain at least two entries for `action=drop_if_equal`; got %q", sourceLabels)
|
||||
}
|
||||
case "keep":
|
||||
if len(sourceLabels) == 0 {
|
||||
return dst, fmt.Errorf("missing `source_labels` for `action=keep`")
|
||||
return nil, fmt.Errorf("missing `source_labels` for `action=keep`")
|
||||
}
|
||||
case "drop":
|
||||
if len(sourceLabels) == 0 {
|
||||
return dst, fmt.Errorf("missing `source_labels` for `action=drop`")
|
||||
return nil, fmt.Errorf("missing `source_labels` for `action=drop`")
|
||||
}
|
||||
case "hashmod":
|
||||
if len(sourceLabels) == 0 {
|
||||
return dst, fmt.Errorf("missing `source_labels` for `action=hashmod`")
|
||||
return nil, fmt.Errorf("missing `source_labels` for `action=hashmod`")
|
||||
}
|
||||
if targetLabel == "" {
|
||||
return dst, fmt.Errorf("missing `target_label` for `action=hashmod`")
|
||||
return nil, fmt.Errorf("missing `target_label` for `action=hashmod`")
|
||||
}
|
||||
if modulus < 1 {
|
||||
return dst, fmt.Errorf("unexpected `modulus` for `action=hashmod`: %d; must be greater than 0", modulus)
|
||||
return nil, fmt.Errorf("unexpected `modulus` for `action=hashmod`: %d; must be greater than 0", modulus)
|
||||
}
|
||||
case "labelmap":
|
||||
case "labelmap_all":
|
||||
case "labeldrop":
|
||||
case "labelkeep":
|
||||
default:
|
||||
return dst, fmt.Errorf("unknown `action` %q", action)
|
||||
return nil, fmt.Errorf("unknown `action` %q", action)
|
||||
}
|
||||
dst = append(dst, ParsedRelabelConfig{
|
||||
return &parsedRelabelConfig{
|
||||
SourceLabels: sourceLabels,
|
||||
Separator: separator,
|
||||
TargetLabel: targetLabel,
|
||||
|
@ -136,8 +182,8 @@ func parseRelabelConfig(dst []ParsedRelabelConfig, rc *RelabelConfig) ([]ParsedR
|
|||
Replacement: replacement,
|
||||
Action: action,
|
||||
|
||||
regexOriginal: regexOriginalCompiled,
|
||||
hasCaptureGroupInTargetLabel: strings.Contains(targetLabel, "$"),
|
||||
hasCaptureGroupInReplacement: strings.Contains(replacement, "$"),
|
||||
})
|
||||
return dst, nil
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -7,12 +7,12 @@ import (
|
|||
|
||||
func TestLoadRelabelConfigsSuccess(t *testing.T) {
|
||||
path := "testdata/relabel_configs_valid.yml"
|
||||
prcs, err := LoadRelabelConfigs(path)
|
||||
pcs, err := LoadRelabelConfigs(path)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot load relabel configs from %q: %s", path, err)
|
||||
}
|
||||
if len(prcs) != 9 {
|
||||
t.Fatalf("unexpected number of relabel configs loaded from %q; got %d; want %d", path, len(prcs), 9)
|
||||
if n := pcs.Len(); n != 9 {
|
||||
t.Fatalf("unexpected number of relabel configs loaded from %q; got %d; want %d", path, n, 9)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ func TestLoadRelabelConfigsFailure(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatalf("expecting non-nil error")
|
||||
}
|
||||
if len(rcs) != 0 {
|
||||
if rcs.Len() != 0 {
|
||||
t.Fatalf("unexpected non-empty rcs: %#v", rcs)
|
||||
}
|
||||
}
|
||||
|
@ -36,14 +36,14 @@ func TestLoadRelabelConfigsFailure(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestParseRelabelConfigsSuccess(t *testing.T) {
|
||||
f := func(rcs []RelabelConfig, prcsExpected []ParsedRelabelConfig) {
|
||||
f := func(rcs []RelabelConfig, pcsExpected *ParsedConfigs) {
|
||||
t.Helper()
|
||||
prcs, err := ParseRelabelConfigs(nil, rcs)
|
||||
pcs, err := ParseRelabelConfigs(rcs)
|
||||
if err != nil {
|
||||
t.Fatalf("unexected error: %s", err)
|
||||
}
|
||||
if !reflect.DeepEqual(prcs, prcsExpected) {
|
||||
t.Fatalf("unexpected prcs; got\n%#v\nwant\n%#v", prcs, prcsExpected)
|
||||
if !reflect.DeepEqual(pcs, pcsExpected) {
|
||||
t.Fatalf("unexpected pcs; got\n%#v\nwant\n%#v", pcs, pcsExpected)
|
||||
}
|
||||
}
|
||||
f(nil, nil)
|
||||
|
@ -52,7 +52,8 @@ func TestParseRelabelConfigsSuccess(t *testing.T) {
|
|||
SourceLabels: []string{"foo", "bar"},
|
||||
TargetLabel: "xxx",
|
||||
},
|
||||
}, []ParsedRelabelConfig{
|
||||
}, &ParsedConfigs{
|
||||
prcs: []*parsedRelabelConfig{
|
||||
{
|
||||
SourceLabels: []string{"foo", "bar"},
|
||||
Separator: ";",
|
||||
|
@ -61,20 +62,22 @@ func TestParseRelabelConfigsSuccess(t *testing.T) {
|
|||
Replacement: "$1",
|
||||
Action: "replace",
|
||||
|
||||
regexOriginal: defaultOriginalRegexForRelabelConfig,
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestParseRelabelConfigsFailure(t *testing.T) {
|
||||
f := func(rcs []RelabelConfig) {
|
||||
t.Helper()
|
||||
prcs, err := ParseRelabelConfigs(nil, rcs)
|
||||
pcs, err := ParseRelabelConfigs(rcs)
|
||||
if err == nil {
|
||||
t.Fatalf("expecting non-nil error")
|
||||
}
|
||||
if len(prcs) > 0 {
|
||||
t.Fatalf("unexpected non-empty prcs: %#v", prcs)
|
||||
if pcs.Len() > 0 {
|
||||
t.Fatalf("unexpected non-empty pcs: %#v", pcs)
|
||||
}
|
||||
}
|
||||
t.Run("invalid-regex", func(t *testing.T) {
|
||||
|
|
|
@ -12,10 +12,10 @@ import (
|
|||
xxhash "github.com/cespare/xxhash/v2"
|
||||
)
|
||||
|
||||
// ParsedRelabelConfig contains parsed `relabel_config`.
|
||||
// parsedRelabelConfig contains parsed `relabel_config`.
|
||||
//
|
||||
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
||||
type ParsedRelabelConfig struct {
|
||||
type parsedRelabelConfig struct {
|
||||
SourceLabels []string
|
||||
Separator string
|
||||
TargetLabel string
|
||||
|
@ -24,30 +24,33 @@ type ParsedRelabelConfig struct {
|
|||
Replacement string
|
||||
Action string
|
||||
|
||||
regexOriginal *regexp.Regexp
|
||||
hasCaptureGroupInTargetLabel bool
|
||||
hasCaptureGroupInReplacement bool
|
||||
}
|
||||
|
||||
// String returns human-readable representation for prc.
|
||||
func (prc *ParsedRelabelConfig) String() string {
|
||||
func (prc *parsedRelabelConfig) String() string {
|
||||
return fmt.Sprintf("SourceLabels=%s, Separator=%s, TargetLabel=%s, Regex=%s, Modulus=%d, Replacement=%s, Action=%s",
|
||||
prc.SourceLabels, prc.Separator, prc.TargetLabel, prc.Regex.String(), prc.Modulus, prc.Replacement, prc.Action)
|
||||
}
|
||||
|
||||
// ApplyRelabelConfigs applies prcs to labels starting from the labelsOffset.
|
||||
// Apply applies pcs to labels starting from the labelsOffset.
|
||||
//
|
||||
// If isFinalize is set, then FinalizeLabels is called on the labels[labelsOffset:].
|
||||
//
|
||||
// The returned labels at labels[labelsOffset:] are sorted.
|
||||
func ApplyRelabelConfigs(labels []prompbmarshal.Label, labelsOffset int, prcs []ParsedRelabelConfig, isFinalize bool) []prompbmarshal.Label {
|
||||
for i := range prcs {
|
||||
tmp := applyRelabelConfig(labels, labelsOffset, &prcs[i])
|
||||
func (pcs *ParsedConfigs) Apply(labels []prompbmarshal.Label, labelsOffset int, isFinalize bool) []prompbmarshal.Label {
|
||||
if pcs != nil {
|
||||
for _, prc := range pcs.prcs {
|
||||
tmp := prc.apply(labels, labelsOffset)
|
||||
if len(tmp) == labelsOffset {
|
||||
// All the labels have been removed.
|
||||
return tmp
|
||||
}
|
||||
labels = tmp
|
||||
}
|
||||
}
|
||||
labels = removeEmptyLabels(labels, labelsOffset)
|
||||
if isFinalize {
|
||||
labels = FinalizeLabels(labels[:labelsOffset], labels[labelsOffset:])
|
||||
|
@ -106,10 +109,10 @@ func FinalizeLabels(dst, src []prompbmarshal.Label) []prompbmarshal.Label {
|
|||
return dst
|
||||
}
|
||||
|
||||
// applyRelabelConfig applies relabeling according to prc.
|
||||
// apply applies relabeling according to prc.
|
||||
//
|
||||
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
||||
func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *ParsedRelabelConfig) []prompbmarshal.Label {
|
||||
func (prc *parsedRelabelConfig) apply(labels []prompbmarshal.Label, labelsOffset int) []prompbmarshal.Label {
|
||||
src := labels[labelsOffset:]
|
||||
switch prc.Action {
|
||||
case "replace":
|
||||
|
@ -150,22 +153,13 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
|||
case "replace_all":
|
||||
bb := relabelBufPool.Get()
|
||||
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete && !prc.hasCaptureGroupInReplacement {
|
||||
// Fast path - string replacement without regexp.
|
||||
sourceStr := string(bb.B)
|
||||
relabelBufPool.Put(bb)
|
||||
valueStr := strings.ReplaceAll(sourceStr, prefix, prc.Replacement)
|
||||
return setLabelValue(labels, labelsOffset, prc.TargetLabel, valueStr)
|
||||
valueStr, ok := prc.replaceStringSubmatches(sourceStr, prc.Replacement, prc.hasCaptureGroupInReplacement)
|
||||
if ok {
|
||||
labels = setLabelValue(labels, labelsOffset, prc.TargetLabel, valueStr)
|
||||
}
|
||||
if !prc.Regex.Match(bb.B) {
|
||||
// Fast path - nothing to replace.
|
||||
relabelBufPool.Put(bb)
|
||||
return labels
|
||||
}
|
||||
sourceStr := string(bb.B) // Make a copy of bb, since it can be returned from ReplaceAllString
|
||||
relabelBufPool.Put(bb)
|
||||
valueStr := prc.Regex.ReplaceAllString(sourceStr, prc.Replacement)
|
||||
return setLabelValue(labels, labelsOffset, prc.TargetLabel, valueStr)
|
||||
case "keep_if_equal":
|
||||
// Keep the entry if all the label values in source_labels are equal.
|
||||
// For example:
|
||||
|
@ -193,14 +187,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
|||
case "keep":
|
||||
bb := relabelBufPool.Get()
|
||||
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||
keep := false
|
||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
||||
// Fast path - simple string match
|
||||
keep = prefix == string(bb.B)
|
||||
} else {
|
||||
// Slow path - match by regexp
|
||||
keep = prc.Regex.Match(bb.B)
|
||||
}
|
||||
keep := prc.matchString(bytesutil.ToUnsafeString(bb.B))
|
||||
relabelBufPool.Put(bb)
|
||||
if !keep {
|
||||
return labels[:labelsOffset]
|
||||
|
@ -209,14 +196,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
|||
case "drop":
|
||||
bb := relabelBufPool.Get()
|
||||
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||
drop := false
|
||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
||||
// Fast path - simple string match
|
||||
drop = prefix == string(bb.B)
|
||||
} else {
|
||||
// Slow path - match by regexp
|
||||
drop = prc.Regex.Match(bb.B)
|
||||
}
|
||||
drop := prc.matchString(bytesutil.ToUnsafeString(bb.B))
|
||||
relabelBufPool.Put(bb)
|
||||
if drop {
|
||||
return labels[:labelsOffset]
|
||||
|
@ -232,42 +212,23 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
|||
case "labelmap":
|
||||
for i := range src {
|
||||
label := &src[i]
|
||||
match := prc.Regex.FindStringSubmatchIndex(label.Name)
|
||||
if match == nil {
|
||||
continue
|
||||
}
|
||||
value := relabelBufPool.Get()
|
||||
value.B = prc.Regex.ExpandString(value.B[:0], prc.Replacement, label.Name, match)
|
||||
labelName := string(value.B)
|
||||
relabelBufPool.Put(value)
|
||||
labelName, ok := prc.replaceFullString(label.Name, prc.Replacement, prc.hasCaptureGroupInReplacement)
|
||||
if ok {
|
||||
labels = setLabelValue(labels, labelsOffset, labelName, label.Value)
|
||||
}
|
||||
}
|
||||
return labels
|
||||
case "labelmap_all":
|
||||
for i := range src {
|
||||
label := &src[i]
|
||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete && !prc.hasCaptureGroupInReplacement {
|
||||
// Fast path - replace without regexp
|
||||
label.Name = strings.ReplaceAll(label.Name, prefix, prc.Replacement)
|
||||
} else {
|
||||
// Slow path - replace with regexp.
|
||||
if !prc.Regex.MatchString(label.Name) {
|
||||
continue
|
||||
}
|
||||
label.Name = prc.Regex.ReplaceAllString(label.Name, prc.Replacement)
|
||||
}
|
||||
label.Name, _ = prc.replaceStringSubmatches(label.Name, prc.Replacement, prc.hasCaptureGroupInReplacement)
|
||||
}
|
||||
return labels
|
||||
case "labeldrop":
|
||||
keepSrc := true
|
||||
for i := range src {
|
||||
label := &src[i]
|
||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
||||
if prefix == label.Name {
|
||||
keepSrc = false
|
||||
break
|
||||
}
|
||||
} else if prc.Regex.MatchString(label.Name) {
|
||||
if prc.matchString(label.Name) {
|
||||
keepSrc = false
|
||||
break
|
||||
}
|
||||
|
@ -278,11 +239,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
|||
dst := labels[:labelsOffset]
|
||||
for i := range src {
|
||||
label := &src[i]
|
||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
||||
if prefix != label.Name {
|
||||
dst = append(dst, *label)
|
||||
}
|
||||
} else if !prc.Regex.MatchString(label.Name) {
|
||||
if !prc.matchString(label.Name) {
|
||||
dst = append(dst, *label)
|
||||
}
|
||||
}
|
||||
|
@ -291,12 +248,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
|||
keepSrc := true
|
||||
for i := range src {
|
||||
label := &src[i]
|
||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
||||
if prefix != label.Name {
|
||||
keepSrc = false
|
||||
break
|
||||
}
|
||||
} else if !prc.Regex.MatchString(src[i].Name) {
|
||||
if !prc.matchString(label.Name) {
|
||||
keepSrc = false
|
||||
break
|
||||
}
|
||||
|
@ -307,11 +259,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
|||
dst := labels[:labelsOffset]
|
||||
for i := range src {
|
||||
label := &src[i]
|
||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
||||
if prefix == label.Name {
|
||||
dst = append(dst, *label)
|
||||
}
|
||||
} else if prc.Regex.MatchString(label.Name) {
|
||||
if prc.matchString(label.Name) {
|
||||
dst = append(dst, *label)
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +270,74 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
|||
}
|
||||
}
|
||||
|
||||
func (prc *ParsedRelabelConfig) expandCaptureGroups(template, source string, match []int) string {
|
||||
func (prc *parsedRelabelConfig) replaceFullString(s, replacement string, hasCaptureGroupInReplacement bool) (string, bool) {
|
||||
prefix, complete := prc.regexOriginal.LiteralPrefix()
|
||||
if complete && !hasCaptureGroupInReplacement {
|
||||
if s == prefix {
|
||||
return replacement, true
|
||||
}
|
||||
return s, false
|
||||
}
|
||||
if !strings.HasPrefix(s, prefix) {
|
||||
return s, false
|
||||
}
|
||||
if replacement == "$1" {
|
||||
// Fast path for commonly used rule for deleting label prefixes such as:
|
||||
//
|
||||
// - action: labelmap
|
||||
// regex: __meta_kubernetes_node_label_(.+)
|
||||
//
|
||||
reStr := prc.regexOriginal.String()
|
||||
if strings.HasPrefix(reStr, prefix) {
|
||||
suffix := s[len(prefix):]
|
||||
reSuffix := reStr[len(prefix):]
|
||||
switch reSuffix {
|
||||
case "(.*)":
|
||||
return suffix, true
|
||||
case "(.+)":
|
||||
if len(suffix) > 0 {
|
||||
return suffix, true
|
||||
}
|
||||
return s, false
|
||||
}
|
||||
}
|
||||
}
|
||||
// Slow path - regexp processing
|
||||
match := prc.Regex.FindStringSubmatchIndex(s)
|
||||
if match == nil {
|
||||
return s, false
|
||||
}
|
||||
bb := relabelBufPool.Get()
|
||||
bb.B = prc.Regex.ExpandString(bb.B[:0], replacement, s, match)
|
||||
result := string(bb.B)
|
||||
relabelBufPool.Put(bb)
|
||||
return result, true
|
||||
}
|
||||
|
||||
func (prc *parsedRelabelConfig) replaceStringSubmatches(s, replacement string, hasCaptureGroupInReplacement bool) (string, bool) {
|
||||
re := prc.regexOriginal
|
||||
prefix, complete := re.LiteralPrefix()
|
||||
if complete && !hasCaptureGroupInReplacement {
|
||||
if !strings.Contains(s, prefix) {
|
||||
return s, false
|
||||
}
|
||||
return strings.ReplaceAll(s, prefix, replacement), true
|
||||
}
|
||||
if !re.MatchString(s) {
|
||||
return s, false
|
||||
}
|
||||
return re.ReplaceAllString(s, replacement), true
|
||||
}
|
||||
|
||||
func (prc *parsedRelabelConfig) matchString(s string) bool {
|
||||
prefix, complete := prc.regexOriginal.LiteralPrefix()
|
||||
if complete {
|
||||
return prefix == s
|
||||
}
|
||||
return strings.HasPrefix(s, prefix) && prc.Regex.MatchString(s)
|
||||
}
|
||||
|
||||
func (prc *parsedRelabelConfig) expandCaptureGroups(template, source string, match []int) string {
|
||||
bb := relabelBufPool.Get()
|
||||
bb.B = prc.Regex.ExpandString(bb.B[:0], template, source, match)
|
||||
s := string(bb.B)
|
||||
|
|
|
@ -2,24 +2,27 @@ package promrelabel
|
|||
|
||||
import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
||||
)
|
||||
|
||||
func TestApplyRelabelConfigs(t *testing.T) {
|
||||
f := func(prcs []ParsedRelabelConfig, labels []prompbmarshal.Label, isFinalize bool, resultExpected []prompbmarshal.Label) {
|
||||
f := func(config string, labels []prompbmarshal.Label, isFinalize bool, resultExpected []prompbmarshal.Label) {
|
||||
t.Helper()
|
||||
result := ApplyRelabelConfigs(labels, 0, prcs, isFinalize)
|
||||
pcs, err := ParseRelabelConfigsData([]byte(config))
|
||||
if err != nil {
|
||||
t.Fatalf("cannot parse %q: %s", config, err)
|
||||
}
|
||||
result := pcs.Apply(labels, 0, isFinalize)
|
||||
if !reflect.DeepEqual(result, resultExpected) {
|
||||
t.Fatalf("unexpected result; got\n%v\nwant\n%v", result, resultExpected)
|
||||
}
|
||||
}
|
||||
t.Run("empty_relabel_configs", func(t *testing.T) {
|
||||
f(nil, nil, false, nil)
|
||||
f(nil, nil, true, nil)
|
||||
f(nil, []prompbmarshal.Label{
|
||||
f("", nil, false, nil)
|
||||
f("", nil, true, nil)
|
||||
f("", []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
|
@ -30,7 +33,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
Value: "bar",
|
||||
},
|
||||
})
|
||||
f(nil, []prompbmarshal.Label{
|
||||
f("", []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
|
@ -55,35 +58,20 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("replace-miss", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
TargetLabel: "bar",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, nil, false, []prompbmarshal.Label{})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "bar",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, nil, false, []prompbmarshal.Label{})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "bar",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace
|
||||
target_label: bar
|
||||
`, nil, false, []prompbmarshal.Label{})
|
||||
f(`
|
||||
- action: replace
|
||||
source_labels: ["foo"]
|
||||
target_label: bar
|
||||
`, nil, false, []prompbmarshal.Label{})
|
||||
f(`
|
||||
- action: replace
|
||||
source_labels: ["foo"]
|
||||
target_label: "bar"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -94,16 +82,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
Value: "yyy",
|
||||
},
|
||||
})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "bar",
|
||||
Regex: regexp.MustCompile(".+"),
|
||||
Replacement: "$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace
|
||||
source_labels: ["foo"]
|
||||
target_label: "bar"
|
||||
regex: ".+"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -116,17 +100,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("replace-hit", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"xxx", "foo"},
|
||||
Separator: ";",
|
||||
TargetLabel: "bar",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "a-$1-b",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace
|
||||
source_labels: ["xxx", "foo"]
|
||||
target_label: "bar"
|
||||
replacement: "a-$1-b"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -143,18 +122,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("replace-hit-target-label-with-capture-group", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"xxx", "foo"},
|
||||
Separator: ";",
|
||||
TargetLabel: "bar-$1",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "a-$1-b",
|
||||
hasCaptureGroupInTargetLabel: true,
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace
|
||||
source_labels: ["xxx", "foo"]
|
||||
target_label: "bar-$1"
|
||||
replacement: "a-$1-b"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -171,35 +144,21 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("replace_all-miss", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace_all",
|
||||
TargetLabel: "bar",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, nil, false, []prompbmarshal.Label{})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace_all",
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "bar",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, nil, false, []prompbmarshal.Label{})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace_all",
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "bar",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace_all
|
||||
source_labels: [foo]
|
||||
target_label: "bar"
|
||||
`, nil, false, []prompbmarshal.Label{})
|
||||
f(`
|
||||
- action: replace_all
|
||||
source_labels: ["foo"]
|
||||
target_label: "bar"
|
||||
`, nil, false, []prompbmarshal.Label{})
|
||||
f(`
|
||||
- action: replace_all
|
||||
source_labels: ["foo"]
|
||||
target_label: "bar"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -210,16 +169,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
Value: "yyy",
|
||||
},
|
||||
})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace_all",
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "bar",
|
||||
Regex: regexp.MustCompile(".+"),
|
||||
Replacement: "$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace_all
|
||||
source_labels: ["foo"]
|
||||
target_label: "bar"
|
||||
regex: ".+"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -232,16 +187,13 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("replace_all-hit", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace_all",
|
||||
SourceLabels: []string{"xxx"},
|
||||
Separator: ";",
|
||||
TargetLabel: "xxx",
|
||||
Regex: regexp.MustCompile("-"),
|
||||
Replacement: ".",
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace_all
|
||||
source_labels: ["xxx"]
|
||||
target_label: "xxx"
|
||||
regex: "-"
|
||||
replacement: "."
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "a-b-c",
|
||||
|
@ -254,17 +206,13 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("replace_all-regex-hit", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace_all",
|
||||
SourceLabels: []string{"xxx", "foo"},
|
||||
Separator: ";",
|
||||
TargetLabel: "xxx",
|
||||
Regex: regexp.MustCompile("(;)"),
|
||||
Replacement: "-$1-",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace_all
|
||||
source_labels: ["xxx", "foo"]
|
||||
target_label: "xxx"
|
||||
regex: "(;)"
|
||||
replacement: "-$1-"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "y;y",
|
||||
|
@ -277,24 +225,16 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("replace-add-multi-labels", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"xxx"},
|
||||
TargetLabel: "bar",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "a-$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"bar"},
|
||||
TargetLabel: "zar",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "b-$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace
|
||||
source_labels: ["xxx"]
|
||||
target_label: "bar"
|
||||
replacement: "a-$1"
|
||||
- action: replace
|
||||
source_labels: ["bar"]
|
||||
target_label: "zar"
|
||||
replacement: "b-$1"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -323,16 +263,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("replace-self", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "foo",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "a-$1",
|
||||
hasCaptureGroupInReplacement: true,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace
|
||||
source_labels: ["foo"]
|
||||
target_label: "foo"
|
||||
replacement: "a-$1"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "aaxx",
|
||||
|
@ -345,14 +281,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("replace-missing-source", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
TargetLabel: "foo",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "foobar",
|
||||
},
|
||||
}, []prompbmarshal.Label{}, true, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: replace
|
||||
target_label: foo
|
||||
replacement: "foobar"
|
||||
`, []prompbmarshal.Label{}, true, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "foobar",
|
||||
|
@ -360,18 +293,14 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("keep_if_equal-miss", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep_if_equal",
|
||||
SourceLabels: []string{"foo", "bar"},
|
||||
},
|
||||
}, nil, true, nil)
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep_if_equal",
|
||||
SourceLabels: []string{"xxx", "bar"},
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: keep_if_equal
|
||||
source_labels: ["foo", "bar"]
|
||||
`, nil, true, nil)
|
||||
f(`
|
||||
- action: keep_if_equal
|
||||
source_labels: ["xxx", "bar"]
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -379,12 +308,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
}, true, []prompbmarshal.Label{})
|
||||
})
|
||||
t.Run("keep_if_equal-hit", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep_if_equal",
|
||||
SourceLabels: []string{"xxx", "bar"},
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: keep_if_equal
|
||||
source_labels: ["xxx", "bar"]
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -405,18 +332,14 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("drop_if_equal-miss", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop_if_equal",
|
||||
SourceLabels: []string{"foo", "bar"},
|
||||
},
|
||||
}, nil, true, nil)
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop_if_equal",
|
||||
SourceLabels: []string{"xxx", "bar"},
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: drop_if_equal
|
||||
source_labels: ["foo", "bar"]
|
||||
`, nil, true, nil)
|
||||
f(`
|
||||
- action: drop_if_equal
|
||||
source_labels: ["xxx", "bar"]
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -429,12 +352,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("drop_if_equal-hit", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop_if_equal",
|
||||
SourceLabels: []string{"xxx", "bar"},
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: drop_if_equal
|
||||
source_labels: [xxx, bar]
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -446,20 +367,16 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
}, true, []prompbmarshal.Label{})
|
||||
})
|
||||
t.Run("keep-miss", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep",
|
||||
SourceLabels: []string{"foo"},
|
||||
Regex: regexp.MustCompile(".+"),
|
||||
},
|
||||
}, nil, true, nil)
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep",
|
||||
SourceLabels: []string{"foo"},
|
||||
Regex: regexp.MustCompile(".+"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: keep
|
||||
source_labels: [foo]
|
||||
regex: ".+"
|
||||
`, nil, true, nil)
|
||||
f(`
|
||||
- action: keep
|
||||
source_labels: [foo]
|
||||
regex: ".+"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -467,13 +384,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
}, true, []prompbmarshal.Label{})
|
||||
})
|
||||
t.Run("keep-hit", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep",
|
||||
SourceLabels: []string{"foo"},
|
||||
Regex: regexp.MustCompile("yyy"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: keep
|
||||
source_labels: [foo]
|
||||
regex: "yyy"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
|
@ -486,13 +401,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("keep-hit-regexp", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep",
|
||||
SourceLabels: []string{"foo"},
|
||||
Regex: regexp.MustCompile(".+"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: keep
|
||||
source_labels: ["foo"]
|
||||
regex: ".+"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
|
@ -505,20 +418,16 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("drop-miss", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop",
|
||||
SourceLabels: []string{"foo"},
|
||||
Regex: regexp.MustCompile(".+"),
|
||||
},
|
||||
}, nil, false, nil)
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop",
|
||||
SourceLabels: []string{"foo"},
|
||||
Regex: regexp.MustCompile(".+"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: drop
|
||||
source_labels: [foo]
|
||||
regex: ".+"
|
||||
`, nil, false, nil)
|
||||
f(`
|
||||
- action: drop
|
||||
source_labels: [foo]
|
||||
regex: ".+"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -531,13 +440,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("drop-hit", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop",
|
||||
SourceLabels: []string{"foo"},
|
||||
Regex: regexp.MustCompile("yyy"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: drop
|
||||
source_labels: [foo]
|
||||
regex: yyy
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
|
@ -545,13 +452,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
}, true, []prompbmarshal.Label{})
|
||||
})
|
||||
t.Run("drop-hit-regexp", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop",
|
||||
SourceLabels: []string{"foo"},
|
||||
Regex: regexp.MustCompile(".+"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: drop
|
||||
source_labels: [foo]
|
||||
regex: ".+"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
|
@ -559,14 +464,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
}, true, []prompbmarshal.Label{})
|
||||
})
|
||||
t.Run("hashmod-miss", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "hashmod",
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "aaa",
|
||||
Modulus: 123,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: hashmod
|
||||
source_labels: [foo]
|
||||
target_label: aaa
|
||||
modulus: 123
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -583,14 +486,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("hashmod-hit", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "hashmod",
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "aaa",
|
||||
Modulus: 123,
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: hashmod
|
||||
source_labels: [foo]
|
||||
target_label: aaa
|
||||
modulus: 123
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
|
@ -606,14 +507,97 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
},
|
||||
})
|
||||
})
|
||||
t.Run("labelmap", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
t.Run("labelmap-copy-label", func(t *testing.T) {
|
||||
f(`
|
||||
- action: labelmap
|
||||
regex: "foo"
|
||||
replacement: "bar"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Action: "labelmap",
|
||||
Regex: regexp.MustCompile("foo(.+)"),
|
||||
Replacement: "$1-x",
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foobar",
|
||||
Value: "aaa",
|
||||
},
|
||||
}, true, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "bar",
|
||||
Value: "yyy",
|
||||
},
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
},
|
||||
{
|
||||
Name: "foobar",
|
||||
Value: "aaa",
|
||||
},
|
||||
})
|
||||
})
|
||||
t.Run("labelmap-remove-prefix-dot-star", func(t *testing.T) {
|
||||
f(`
|
||||
- action: labelmap
|
||||
regex: "foo(.*)"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xoo",
|
||||
Value: "yyy",
|
||||
},
|
||||
{
|
||||
Name: "foobar",
|
||||
Value: "aaa",
|
||||
},
|
||||
}, true, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "bar",
|
||||
Value: "aaa",
|
||||
},
|
||||
{
|
||||
Name: "foobar",
|
||||
Value: "aaa",
|
||||
},
|
||||
{
|
||||
Name: "xoo",
|
||||
Value: "yyy",
|
||||
},
|
||||
})
|
||||
})
|
||||
t.Run("labelmap-remove-prefix-dot-plus", func(t *testing.T) {
|
||||
f(`
|
||||
- action: labelmap
|
||||
regex: "foo(.+)"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
},
|
||||
{
|
||||
Name: "foobar",
|
||||
Value: "aaa",
|
||||
},
|
||||
}, true, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "bar",
|
||||
Value: "aaa",
|
||||
},
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
},
|
||||
{
|
||||
Name: "foobar",
|
||||
Value: "aaa",
|
||||
},
|
||||
})
|
||||
})
|
||||
t.Run("labelmap-regex", func(t *testing.T) {
|
||||
f(`
|
||||
- action: labelmap
|
||||
regex: "foo(.+)"
|
||||
replacement: "$1-x"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "yyy",
|
||||
|
@ -638,13 +622,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("labelmap_all", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelmap_all",
|
||||
Regex: regexp.MustCompile(`\.`),
|
||||
Replacement: "-",
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labelmap_all
|
||||
regex: "\\."
|
||||
replacement: "-"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo.bar.baz",
|
||||
Value: "yyy",
|
||||
|
@ -665,13 +647,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("labelmap_all-regexp", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelmap_all",
|
||||
Regex: regexp.MustCompile(`ba(.)`),
|
||||
Replacement: "${1}ss",
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labelmap_all
|
||||
regex: "ba(.)"
|
||||
replacement: "${1}ss"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "foo.bar.baz",
|
||||
Value: "yyy",
|
||||
|
@ -692,12 +672,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("labeldrop", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labeldrop",
|
||||
Regex: regexp.MustCompile("dropme"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labeldrop
|
||||
regex: dropme
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "aaa",
|
||||
Value: "bbb",
|
||||
|
@ -708,12 +686,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
Value: "bbb",
|
||||
},
|
||||
})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labeldrop",
|
||||
Regex: regexp.MustCompile("dropme"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labeldrop
|
||||
regex: dropme
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -738,12 +714,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("labeldrop-regexp", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labeldrop",
|
||||
Regex: regexp.MustCompile("dropme.*"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labeldrop
|
||||
regex: "dropme.*"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "aaa",
|
||||
Value: "bbb",
|
||||
|
@ -754,12 +728,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
Value: "bbb",
|
||||
},
|
||||
})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labeldrop",
|
||||
Regex: regexp.MustCompile("dropme.*"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labeldrop
|
||||
regex: "dropme.*"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "xxx",
|
||||
Value: "yyy",
|
||||
|
@ -784,12 +756,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("labelkeep", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelkeep",
|
||||
Regex: regexp.MustCompile("keepme"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labelkeep
|
||||
regex: "keepme"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "keepme",
|
||||
Value: "aaa",
|
||||
|
@ -800,12 +770,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
Value: "aaa",
|
||||
},
|
||||
})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelkeep",
|
||||
Regex: regexp.MustCompile("keepme"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labelkeep
|
||||
regex: keepme
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "keepme",
|
||||
Value: "aaa",
|
||||
|
@ -826,12 +794,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
})
|
||||
})
|
||||
t.Run("labelkeep-regexp", func(t *testing.T) {
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelkeep",
|
||||
Regex: regexp.MustCompile("keepme.*"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labelkeep
|
||||
regex: "keepme.*"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "keepme",
|
||||
Value: "aaa",
|
||||
|
@ -842,12 +808,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
|||
Value: "aaa",
|
||||
},
|
||||
})
|
||||
f([]ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelkeep",
|
||||
Regex: regexp.MustCompile("keepme.*"),
|
||||
},
|
||||
}, []prompbmarshal.Label{
|
||||
f(`
|
||||
- action: labelkeep
|
||||
regex: "keepme.*"
|
||||
`, []prompbmarshal.Label{
|
||||
{
|
||||
Name: "keepme",
|
||||
Value: "aaa",
|
||||
|
|
|
@ -2,7 +2,6 @@ package promrelabel
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
||||
|
@ -10,15 +9,11 @@ import (
|
|||
|
||||
func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||
b.Run("replace-label-copy", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"id"},
|
||||
TargetLabel: "__name__",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "$1",
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: replace
|
||||
source_labels: [id]
|
||||
target_label: __name__
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -35,7 +30,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != len(labelsOrig) {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
||||
}
|
||||
|
@ -55,14 +50,11 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("replace-set-label", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
TargetLabel: "__name__",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "foobar",
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: replace
|
||||
target_label: __name__
|
||||
replacement: foobar
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -79,7 +71,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != len(labelsOrig) {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
||||
}
|
||||
|
@ -99,14 +91,11 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("replace-add-label", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
TargetLabel: "aaa",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "foobar",
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: replace
|
||||
target_label: aaa
|
||||
replacement: foobar
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -119,7 +108,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 2 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 2, labels))
|
||||
}
|
||||
|
@ -139,15 +128,12 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("replace-mismatch", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"non-existing-label"},
|
||||
TargetLabel: "id",
|
||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
||||
Replacement: "$1",
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: replace
|
||||
source_labels: ["non-existing-label"]
|
||||
target_label: id
|
||||
regex: "(foobar)-.*"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -164,7 +150,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != len(labelsOrig) {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
||||
}
|
||||
|
@ -184,15 +170,12 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("replace-match-regex", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "replace",
|
||||
SourceLabels: []string{"id"},
|
||||
TargetLabel: "id",
|
||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
||||
Replacement: "$1",
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: replace
|
||||
source_labels: [id]
|
||||
target_label: id
|
||||
regex: "(foobar)-.*"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -209,7 +192,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != len(labelsOrig) {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
||||
}
|
||||
|
@ -229,13 +212,11 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("drop-mismatch", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop",
|
||||
SourceLabels: []string{"non-existing-label"},
|
||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: drop
|
||||
source_labels: ["non-existing-label"]
|
||||
regex: "(foobar)-.*"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -252,7 +233,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != len(labelsOrig) {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
||||
}
|
||||
|
@ -272,13 +253,11 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("drop-match", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop",
|
||||
SourceLabels: []string{"id"},
|
||||
Regex: regexp.MustCompile("yes"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: drop
|
||||
source_labels: [id]
|
||||
regex: yes
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -295,7 +274,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 0 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels))
|
||||
}
|
||||
|
@ -303,13 +282,11 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("drop-match-regexp", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop",
|
||||
SourceLabels: []string{"id"},
|
||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: drop
|
||||
source_labels: [id]
|
||||
regex: "(foobar)-.*"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -326,7 +303,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 0 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels))
|
||||
}
|
||||
|
@ -334,13 +311,11 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("keep-mismatch", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep",
|
||||
SourceLabels: []string{"non-existing-label"},
|
||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: keep
|
||||
source_labels: ["non-existing-label"]
|
||||
regex: "(foobar)-.*"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -357,7 +332,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 0 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels))
|
||||
}
|
||||
|
@ -365,13 +340,11 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("keep-match", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep",
|
||||
SourceLabels: []string{"id"},
|
||||
Regex: regexp.MustCompile("yes"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: keep
|
||||
source_labels: [id]
|
||||
regex: yes
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -388,7 +361,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != len(labelsOrig) {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
||||
}
|
||||
|
@ -408,13 +381,11 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("keep-match-regexp", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "keep",
|
||||
SourceLabels: []string{"id"},
|
||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: keep
|
||||
source_labels: [id]
|
||||
regex: "(foobar)-.*"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -431,7 +402,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != len(labelsOrig) {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
||||
}
|
||||
|
@ -451,12 +422,10 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("labeldrop-mismatch", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labeldrop",
|
||||
Regex: regexp.MustCompile("non-existing-label"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: labeldrop
|
||||
regex: "non-existing-label"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -473,7 +442,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != len(labelsOrig) {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
||||
}
|
||||
|
@ -493,12 +462,10 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("labeldrop-match", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labeldrop",
|
||||
Regex: regexp.MustCompile("id"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: labeldrop
|
||||
regex: id
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -515,7 +482,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 1 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels))
|
||||
}
|
||||
|
@ -529,12 +496,10 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("labeldrop-match-regexp", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labeldrop",
|
||||
Regex: regexp.MustCompile("id.*"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: labeldrop
|
||||
regex: "id.*"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -551,7 +516,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 1 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels))
|
||||
}
|
||||
|
@ -565,12 +530,10 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("labelkeep-mismatch", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelkeep",
|
||||
Regex: regexp.MustCompile("non-existing-label"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: labelkeep
|
||||
regex: "non-existing-label"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -587,7 +550,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 0 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels))
|
||||
}
|
||||
|
@ -595,12 +558,10 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("labelkeep-match", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelkeep",
|
||||
Regex: regexp.MustCompile("id"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: labelkeep
|
||||
regex: id
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -617,7 +578,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 1 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels))
|
||||
}
|
||||
|
@ -631,12 +592,10 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
b.Run("labelkeep-match-regexp", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelkeep",
|
||||
Regex: regexp.MustCompile("id.*"),
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: labelkeep
|
||||
regex: "id.*"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -653,7 +612,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 1 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels))
|
||||
}
|
||||
|
@ -666,19 +625,12 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
}
|
||||
})
|
||||
})
|
||||
b.Run("labelmap", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "labelmap",
|
||||
Regex: regexp.MustCompile("a(.*)"),
|
||||
Replacement: "$1",
|
||||
},
|
||||
}
|
||||
b.Run("labelmap-mismatch", func(b *testing.B) {
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: labelmap
|
||||
regex: "a(.*)"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "aabc",
|
||||
Value: "foobar-random-string-here",
|
||||
},
|
||||
{
|
||||
Name: "foo",
|
||||
Value: "bar",
|
||||
|
@ -690,8 +642,38 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
if len(labels) != 3 {
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 1 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 3, labels))
|
||||
}
|
||||
if labels[0].Name != "foo" {
|
||||
panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "foo"))
|
||||
}
|
||||
if labels[0].Value != "bar" {
|
||||
panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "bar"))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
b.Run("labelmap-match-remove-prefix", func(b *testing.B) {
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: labelmap
|
||||
regex: "a(.*)"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "aabc",
|
||||
Value: "foobar-random-string-here",
|
||||
},
|
||||
}
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(1)
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 2 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 3, labels))
|
||||
}
|
||||
if labels[0].Name != "aabc" {
|
||||
|
@ -706,24 +688,52 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
if labels[1].Value != "foobar-random-string-here" {
|
||||
panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[1].Value, "foobar-random-string-here"))
|
||||
}
|
||||
if labels[2].Name != "foo" {
|
||||
panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[2].Name, "foo"))
|
||||
}
|
||||
if labels[2].Value != "bar" {
|
||||
panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[2].Value, "bar"))
|
||||
})
|
||||
})
|
||||
b.Run("labelmap-match-regexp", func(b *testing.B) {
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: labelmap
|
||||
regex: "(.*)bc"
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "aabc",
|
||||
Value: "foobar-random-string-here",
|
||||
},
|
||||
}
|
||||
b.ReportAllocs()
|
||||
b.SetBytes(1)
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != 2 {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 3, labels))
|
||||
}
|
||||
if labels[0].Name != "aa" {
|
||||
panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "aa"))
|
||||
}
|
||||
if labels[0].Value != "foobar-random-string-here" {
|
||||
panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "foobar-random-string-here"))
|
||||
}
|
||||
if labels[1].Name != "aabc" {
|
||||
panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "aabc"))
|
||||
}
|
||||
if labels[1].Value != "foobar-random-string-here" {
|
||||
panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[1].Value, "foobar-random-string-here"))
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
b.Run("hashmod", func(b *testing.B) {
|
||||
prcs := []ParsedRelabelConfig{
|
||||
{
|
||||
Action: "hashmod",
|
||||
SourceLabels: []string{"id"},
|
||||
TargetLabel: "id",
|
||||
Modulus: 23,
|
||||
},
|
||||
}
|
||||
pcs := mustParseRelabelConfigs(`
|
||||
- action: hashmod
|
||||
source_labels: [id]
|
||||
target_label: id
|
||||
modulus: 23
|
||||
`)
|
||||
labelsOrig := []prompbmarshal.Label{
|
||||
{
|
||||
Name: "__name__",
|
||||
|
@ -740,7 +750,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
var labels []prompbmarshal.Label
|
||||
for pb.Next() {
|
||||
labels = append(labels[:0], labelsOrig...)
|
||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
||||
labels = pcs.Apply(labels, 0, true)
|
||||
if len(labels) != len(labelsOrig) {
|
||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
||||
}
|
||||
|
@ -760,3 +770,11 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
func mustParseRelabelConfigs(config string) *ParsedConfigs {
|
||||
pcs, err := ParseRelabelConfigsData([]byte(config))
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("unexpected error: %w", err))
|
||||
}
|
||||
return pcs
|
||||
}
|
||||
|
|
|
@ -482,13 +482,11 @@ func getScrapeWorkConfig(sc *ScrapeConfig, baseDir string, globalCfg *GlobalConf
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse auth config for `job_name` %q: %w", jobName, err)
|
||||
}
|
||||
var relabelConfigs []promrelabel.ParsedRelabelConfig
|
||||
relabelConfigs, err = promrelabel.ParseRelabelConfigs(relabelConfigs[:0], sc.RelabelConfigs)
|
||||
relabelConfigs, err := promrelabel.ParseRelabelConfigs(sc.RelabelConfigs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse `relabel_configs` for `job_name` %q: %w", jobName, err)
|
||||
}
|
||||
var metricRelabelConfigs []promrelabel.ParsedRelabelConfig
|
||||
metricRelabelConfigs, err = promrelabel.ParseRelabelConfigs(metricRelabelConfigs[:0], sc.MetricRelabelConfigs)
|
||||
metricRelabelConfigs, err := promrelabel.ParseRelabelConfigs(sc.MetricRelabelConfigs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse `metric_relabel_configs` for `job_name` %q: %w", jobName, err)
|
||||
}
|
||||
|
@ -527,8 +525,8 @@ type scrapeWorkConfig struct {
|
|||
honorLabels bool
|
||||
honorTimestamps bool
|
||||
externalLabels map[string]string
|
||||
relabelConfigs []promrelabel.ParsedRelabelConfig
|
||||
metricRelabelConfigs []promrelabel.ParsedRelabelConfig
|
||||
relabelConfigs *promrelabel.ParsedConfigs
|
||||
metricRelabelConfigs *promrelabel.ParsedConfigs
|
||||
sampleLimit int
|
||||
disableCompression bool
|
||||
disableKeepAlive bool
|
||||
|
@ -695,7 +693,7 @@ func appendScrapeWork(dst []*ScrapeWork, swc *scrapeWorkConfig, target string, e
|
|||
// Reduce memory usage by interning all the strings in originalLabels.
|
||||
internLabelStrings(originalLabels)
|
||||
}
|
||||
labels = promrelabel.ApplyRelabelConfigs(labels, 0, swc.relabelConfigs, false)
|
||||
labels = swc.relabelConfigs.Apply(labels, 0, false)
|
||||
labels = promrelabel.RemoveMetaLabels(labels[:0], labels)
|
||||
// Remove references to already deleted labels, so GC could clean strings for label name and label value past len(labels).
|
||||
// This should reduce memory usage when relabeling creates big number of temporary labels with long names and/or values.
|
||||
|
|
|
@ -4,13 +4,11 @@ import (
|
|||
"crypto/tls"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
|
||||
)
|
||||
|
||||
func TestLoadStaticConfigs(t *testing.T) {
|
||||
|
@ -1034,13 +1032,6 @@ scrape_configs:
|
|||
},
|
||||
})
|
||||
|
||||
prcs, err := promrelabel.ParseRelabelConfigs(nil, []promrelabel.RelabelConfig{{
|
||||
SourceLabels: []string{"foo"},
|
||||
TargetLabel: "abc",
|
||||
}})
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when parsing relabel configs: %s", err)
|
||||
}
|
||||
f(`
|
||||
scrape_configs:
|
||||
- job_name: foo
|
||||
|
@ -1077,7 +1068,10 @@ scrape_configs:
|
|||
},
|
||||
},
|
||||
AuthConfig: &promauth.Config{},
|
||||
MetricRelabelConfigs: prcs,
|
||||
MetricRelabelConfigs: mustParseRelabelConfigs(`
|
||||
- source_labels: [foo]
|
||||
target_label: abc
|
||||
`),
|
||||
jobNameOriginal: "foo",
|
||||
},
|
||||
})
|
||||
|
@ -1374,8 +1368,6 @@ scrape_configs:
|
|||
})
|
||||
}
|
||||
|
||||
var defaultRegexForRelabelConfig = regexp.MustCompile("^(.*)$")
|
||||
|
||||
func equalStaticConfigForScrapeWorks(a, b []*ScrapeWork) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"math"
|
||||
"math/bits"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
|
@ -76,7 +75,7 @@ type ScrapeWork struct {
|
|||
ProxyURL proxy.URL
|
||||
|
||||
// Optional `metric_relabel_configs`.
|
||||
MetricRelabelConfigs []promrelabel.ParsedRelabelConfig
|
||||
MetricRelabelConfigs *promrelabel.ParsedConfigs
|
||||
|
||||
// The maximum number of metrics to scrape after relabeling.
|
||||
SampleLimit int
|
||||
|
@ -105,18 +104,10 @@ func (sw *ScrapeWork) key() string {
|
|||
key := fmt.Sprintf("ScrapeURL=%s, ScrapeInterval=%s, ScrapeTimeout=%s, HonorLabels=%v, HonorTimestamps=%v, Labels=%s, "+
|
||||
"AuthConfig=%s, MetricRelabelConfigs=%s, SampleLimit=%d, DisableCompression=%v, DisableKeepAlive=%v, StreamParse=%v, ScrapeAlignInterval=%s",
|
||||
sw.ScrapeURL, sw.ScrapeInterval, sw.ScrapeTimeout, sw.HonorLabels, sw.HonorTimestamps, sw.LabelsString(),
|
||||
sw.AuthConfig.String(), sw.metricRelabelConfigsString(), sw.SampleLimit, sw.DisableCompression, sw.DisableKeepAlive, sw.StreamParse, sw.ScrapeAlignInterval)
|
||||
sw.AuthConfig.String(), sw.MetricRelabelConfigs.String(), sw.SampleLimit, sw.DisableCompression, sw.DisableKeepAlive, sw.StreamParse, sw.ScrapeAlignInterval)
|
||||
return key
|
||||
}
|
||||
|
||||
func (sw *ScrapeWork) metricRelabelConfigsString() string {
|
||||
var sb strings.Builder
|
||||
for _, prc := range sw.MetricRelabelConfigs {
|
||||
fmt.Fprintf(&sb, "%s", prc.String())
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// Job returns job for the ScrapeWork
|
||||
func (sw *ScrapeWork) Job() string {
|
||||
return promrelabel.GetLabelValueByName(sw.Labels, "job")
|
||||
|
@ -503,7 +494,7 @@ func (sw *scrapeWork) addRowToTimeseries(wc *writeRequestCtx, r *parser.Row, tim
|
|||
labelsLen := len(wc.labels)
|
||||
wc.labels = appendLabels(wc.labels, r.Metric, r.Tags, sw.Config.Labels, sw.Config.HonorLabels)
|
||||
if needRelabel {
|
||||
wc.labels = promrelabel.ApplyRelabelConfigs(wc.labels, labelsLen, sw.Config.MetricRelabelConfigs, true)
|
||||
wc.labels = sw.Config.MetricRelabelConfigs.Apply(wc.labels, labelsLen, true)
|
||||
} else {
|
||||
wc.labels = promrelabel.FinalizeLabels(wc.labels[:labelsLen], wc.labels[labelsLen:])
|
||||
promrelabel.SortLabels(wc.labels[labelsLen:])
|
||||
|
|
|
@ -2,7 +2,6 @@ package promscrape
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -102,7 +101,8 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
|
|||
sw.PushData = func(wr *prompbmarshal.WriteRequest) {
|
||||
pushDataCalls++
|
||||
if len(wr.Timeseries) > len(timeseriesExpected) {
|
||||
pushDataErr = fmt.Errorf("too many time series obtained; got %d; want %d", len(wr.Timeseries), len(timeseriesExpected))
|
||||
pushDataErr = fmt.Errorf("too many time series obtained; got %d; want %d\ngot\n%+v\nwant\n%+v",
|
||||
len(wr.Timeseries), len(timeseriesExpected), wr.Timeseries, timeseriesExpected)
|
||||
return
|
||||
}
|
||||
tsExpected := timeseriesExpected[:len(wr.Timeseries)]
|
||||
|
@ -271,20 +271,14 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
|
|||
Value: "foo.com",
|
||||
},
|
||||
},
|
||||
MetricRelabelConfigs: []promrelabel.ParsedRelabelConfig{
|
||||
{
|
||||
SourceLabels: []string{"__address__", "job"},
|
||||
Separator: "/",
|
||||
TargetLabel: "instance",
|
||||
Regex: defaultRegexForRelabelConfig,
|
||||
Replacement: "$1",
|
||||
Action: "replace",
|
||||
},
|
||||
{
|
||||
Action: "labeldrop",
|
||||
Regex: regexp.MustCompile("^c$"),
|
||||
},
|
||||
},
|
||||
MetricRelabelConfigs: mustParseRelabelConfigs(`
|
||||
- action: replace
|
||||
source_labels: ["__address__", "job"]
|
||||
separator: "/"
|
||||
target_label: "instance"
|
||||
- action: labeldrop
|
||||
regex: c
|
||||
`),
|
||||
}, `
|
||||
foo{bar="baz",job="xx",instance="foo.com/xx"} 34.44 123
|
||||
bar{a="b",job="xx",instance="foo.com/xx"} -3e4 123
|
||||
|
@ -311,18 +305,15 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
|
|||
Value: "foo.com",
|
||||
},
|
||||
},
|
||||
MetricRelabelConfigs: []promrelabel.ParsedRelabelConfig{
|
||||
{
|
||||
Action: "drop",
|
||||
SourceLabels: []string{"a", "c"},
|
||||
Regex: regexp.MustCompile("^bd$"),
|
||||
},
|
||||
{
|
||||
Action: "drop",
|
||||
SourceLabels: []string{"__name__"},
|
||||
Regex: regexp.MustCompile("^(dropme|up)$"),
|
||||
},
|
||||
},
|
||||
MetricRelabelConfigs: mustParseRelabelConfigs(`
|
||||
- action: drop
|
||||
separator: ""
|
||||
source_labels: [a, c]
|
||||
regex: "^bd$"
|
||||
- action: drop
|
||||
source_labels: [__name__]
|
||||
regex: "dropme|up"
|
||||
`),
|
||||
}, `
|
||||
foo{bar="baz",job="xx",instance="foo.com"} 34.44 123
|
||||
up{job="xx",instance="foo.com"} 1 123
|
||||
|
@ -440,3 +431,11 @@ func timeseriesToString(ts *prompbmarshal.TimeSeries) string {
|
|||
fmt.Fprintf(&sb, "%g %d", s.Value, s.Timestamp)
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func mustParseRelabelConfigs(config string) *promrelabel.ParsedConfigs {
|
||||
pcs, err := promrelabel.ParseRelabelConfigsData([]byte(config))
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("cannot parse %q: %w", config, err))
|
||||
}
|
||||
return pcs
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue