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",
|
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))
|
len(*relabelConfigPaths), len(*remoteWriteURLs))
|
||||||
}
|
}
|
||||||
rcs.perURL = make([][]promrelabel.ParsedRelabelConfig, len(*remoteWriteURLs))
|
rcs.perURL = make([]*promrelabel.ParsedConfigs, len(*remoteWriteURLs))
|
||||||
for i, path := range *relabelConfigPaths {
|
for i, path := range *relabelConfigPaths {
|
||||||
if len(path) == 0 {
|
if len(path) == 0 {
|
||||||
// Skip empty relabel config.
|
// Skip empty relabel config.
|
||||||
|
@ -57,8 +57,8 @@ func loadRelabelConfigs() (*relabelConfigs, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type relabelConfigs struct {
|
type relabelConfigs struct {
|
||||||
global []promrelabel.ParsedRelabelConfig
|
global *promrelabel.ParsedConfigs
|
||||||
perURL [][]promrelabel.ParsedRelabelConfig
|
perURL []*promrelabel.ParsedConfigs
|
||||||
}
|
}
|
||||||
|
|
||||||
// initLabelsGlobal must be called after parsing command-line flags.
|
// 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 {
|
func (rctx *relabelCtx) applyRelabeling(tss []prompbmarshal.TimeSeries, extraLabels []prompbmarshal.Label, pcs *promrelabel.ParsedConfigs) []prompbmarshal.TimeSeries {
|
||||||
if len(extraLabels) == 0 && len(prcs) == 0 {
|
if len(extraLabels) == 0 && pcs.Len() == 0 {
|
||||||
// Nothing to change.
|
// Nothing to change.
|
||||||
return tss
|
return tss
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ func (rctx *relabelCtx) applyRelabeling(tss []prompbmarshal.TimeSeries, extraLab
|
||||||
labels = append(labels, *extraLabel)
|
labels = append(labels, *extraLabel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
labels = promrelabel.ApplyRelabelConfigs(labels, labelsLen, prcs, true)
|
labels = pcs.Apply(labels, labelsLen, true)
|
||||||
if len(labels) == labelsLen {
|
if len(labels) == labelsLen {
|
||||||
// Drop the current time series, since relabeling removed all the labels.
|
// Drop the current time series, since relabeling removed all the labels.
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -142,8 +142,8 @@ func Stop() {
|
||||||
func Push(wr *prompbmarshal.WriteRequest) {
|
func Push(wr *prompbmarshal.WriteRequest) {
|
||||||
var rctx *relabelCtx
|
var rctx *relabelCtx
|
||||||
rcs := allRelabelConfigs.Load().(*relabelConfigs)
|
rcs := allRelabelConfigs.Load().(*relabelConfigs)
|
||||||
prcsGlobal := rcs.global
|
pcsGlobal := rcs.global
|
||||||
if len(prcsGlobal) > 0 || len(labelsGlobal) > 0 {
|
if pcsGlobal.Len() > 0 || len(labelsGlobal) > 0 {
|
||||||
rctx = getRelabelCtx()
|
rctx = getRelabelCtx()
|
||||||
}
|
}
|
||||||
tss := wr.Timeseries
|
tss := wr.Timeseries
|
||||||
|
@ -167,7 +167,7 @@ func Push(wr *prompbmarshal.WriteRequest) {
|
||||||
}
|
}
|
||||||
if rctx != nil {
|
if rctx != nil {
|
||||||
tssBlockLen := len(tssBlock)
|
tssBlockLen := len(tssBlock)
|
||||||
tssBlock = rctx.applyRelabeling(tssBlock, labelsGlobal, prcsGlobal)
|
tssBlock = rctx.applyRelabeling(tssBlock, labelsGlobal, pcsGlobal)
|
||||||
globalRelabelMetricsDropped.Add(tssBlockLen - len(tssBlock))
|
globalRelabelMetricsDropped.Add(tssBlockLen - len(tssBlock))
|
||||||
}
|
}
|
||||||
for _, rwctx := range rwctxs {
|
for _, rwctx := range rwctxs {
|
||||||
|
@ -240,8 +240,8 @@ func (rwctx *remoteWriteCtx) Push(tss []prompbmarshal.TimeSeries) {
|
||||||
var rctx *relabelCtx
|
var rctx *relabelCtx
|
||||||
var v *[]prompbmarshal.TimeSeries
|
var v *[]prompbmarshal.TimeSeries
|
||||||
rcs := allRelabelConfigs.Load().(*relabelConfigs)
|
rcs := allRelabelConfigs.Load().(*relabelConfigs)
|
||||||
prcs := rcs.perURL[rwctx.idx]
|
pcs := rcs.perURL[rwctx.idx]
|
||||||
if len(prcs) > 0 {
|
if pcs.Len() > 0 {
|
||||||
rctx = getRelabelCtx()
|
rctx = getRelabelCtx()
|
||||||
// Make a copy of tss before applying relabeling in order to prevent
|
// Make a copy of tss before applying relabeling in order to prevent
|
||||||
// from affecting time series for other remoteWrite.url configs.
|
// 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)
|
v = tssRelabelPool.Get().(*[]prompbmarshal.TimeSeries)
|
||||||
tss = append(*v, tss...)
|
tss = append(*v, tss...)
|
||||||
tssLen := len(tss)
|
tssLen := len(tss)
|
||||||
tss = rctx.applyRelabeling(tss, nil, prcs)
|
tss = rctx.applyRelabeling(tss, nil, pcs)
|
||||||
rwctx.relabelMetricsDropped.Add(tssLen - len(tss))
|
rwctx.relabelMetricsDropped.Add(tssLen - len(tss))
|
||||||
}
|
}
|
||||||
pss := rwctx.pss
|
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.
|
// Init must be called after flag.Parse and before using the relabel package.
|
||||||
func Init() {
|
func Init() {
|
||||||
prcs, err := loadRelabelConfig()
|
pcs, err := loadRelabelConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Fatalf("cannot load relabelConfig: %s", err)
|
logger.Fatalf("cannot load relabelConfig: %s", err)
|
||||||
}
|
}
|
||||||
prcsGlobal.Store(&prcs)
|
pcsGlobal.Store(pcs)
|
||||||
if len(*relabelConfig) == 0 {
|
if len(*relabelConfig) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -31,34 +31,34 @@ func Init() {
|
||||||
go func() {
|
go func() {
|
||||||
for range sighupCh {
|
for range sighupCh {
|
||||||
logger.Infof("received SIGHUP; reloading -relabelConfig=%q...", *relabelConfig)
|
logger.Infof("received SIGHUP; reloading -relabelConfig=%q...", *relabelConfig)
|
||||||
prcs, err := loadRelabelConfig()
|
pcs, err := loadRelabelConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("cannot load the updated relabelConfig: %s; preserving the previous config", err)
|
logger.Errorf("cannot load the updated relabelConfig: %s; preserving the previous config", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
prcsGlobal.Store(&prcs)
|
pcsGlobal.Store(pcs)
|
||||||
logger.Infof("successfully reloaded -relabelConfig=%q", *relabelConfig)
|
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 {
|
if len(*relabelConfig) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
prcs, err := promrelabel.LoadRelabelConfigs(*relabelConfig)
|
pcs, err := promrelabel.LoadRelabelConfigs(*relabelConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error when reading -relabelConfig=%q: %w", *relabelConfig, err)
|
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.
|
// HasRelabeling returns true if there is global relabeling.
|
||||||
func HasRelabeling() bool {
|
func HasRelabeling() bool {
|
||||||
prcs := prcsGlobal.Load().(*[]promrelabel.ParsedRelabelConfig)
|
pcs := pcsGlobal.Load().(*promrelabel.ParsedConfigs)
|
||||||
return len(*prcs) > 0
|
return pcs.Len() > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ctx holds relabeling context.
|
// Ctx holds relabeling context.
|
||||||
|
@ -77,8 +77,8 @@ func (ctx *Ctx) Reset() {
|
||||||
//
|
//
|
||||||
// The returned labels are valid until the next call to ApplyRelabeling.
|
// The returned labels are valid until the next call to ApplyRelabeling.
|
||||||
func (ctx *Ctx) ApplyRelabeling(labels []prompb.Label) []prompb.Label {
|
func (ctx *Ctx) ApplyRelabeling(labels []prompb.Label) []prompb.Label {
|
||||||
prcs := prcsGlobal.Load().(*[]promrelabel.ParsedRelabelConfig)
|
pcs := pcsGlobal.Load().(*promrelabel.ParsedConfigs)
|
||||||
if len(*prcs) == 0 {
|
if pcs.Len() == 0 {
|
||||||
// There are no relabeling rules.
|
// There are no relabeling rules.
|
||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ func (ctx *Ctx) ApplyRelabeling(labels []prompb.Label) []prompb.Label {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply relabeling
|
// Apply relabeling
|
||||||
tmpLabels = promrelabel.ApplyRelabelConfigs(tmpLabels, 0, *prcs, true)
|
tmpLabels = pcs.Apply(tmpLabels, 0, true)
|
||||||
ctx.tmpLabels = tmpLabels
|
ctx.tmpLabels = tmpLabels
|
||||||
if len(tmpLabels) == 0 {
|
if len(tmpLabels) == 0 {
|
||||||
metricsDropped.Inc()
|
metricsDropped.Inc()
|
||||||
|
|
|
@ -23,38 +23,78 @@ type RelabelConfig struct {
|
||||||
Action string `yaml:"action,omitempty"`
|
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.
|
// 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)
|
data, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot read `relabel_configs` from %q: %w", path, err)
|
return nil, fmt.Errorf("cannot read `relabel_configs` from %q: %w", path, err)
|
||||||
}
|
}
|
||||||
data = envtemplate.Replace(data)
|
data = envtemplate.Replace(data)
|
||||||
var rcs []RelabelConfig
|
pcs, err := ParseRelabelConfigsData(data)
|
||||||
if err := yaml.UnmarshalStrict(data, &rcs); err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot unmarshal `relabel_configs` from %q: %w", path, err)
|
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.
|
// ParseRelabelConfigs parses rcs to dst.
|
||||||
func ParseRelabelConfigs(dst []ParsedRelabelConfig, rcs []RelabelConfig) ([]ParsedRelabelConfig, error) {
|
func ParseRelabelConfigs(rcs []RelabelConfig) (*ParsedConfigs, error) {
|
||||||
if len(rcs) == 0 {
|
if len(rcs) == 0 {
|
||||||
return dst, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
prcs := make([]*parsedRelabelConfig, len(rcs))
|
||||||
for i := range rcs {
|
for i := range rcs {
|
||||||
var err error
|
prc, err := parseRelabelConfig(&rcs[i])
|
||||||
dst, err = parseRelabelConfig(dst, &rcs[i])
|
|
||||||
if err != nil {
|
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
|
sourceLabels := rc.SourceLabels
|
||||||
separator := ";"
|
separator := ";"
|
||||||
if rc.Separator != nil {
|
if rc.Separator != nil {
|
||||||
|
@ -62,6 +102,7 @@ func parseRelabelConfig(dst []ParsedRelabelConfig, rc *RelabelConfig) ([]ParsedR
|
||||||
}
|
}
|
||||||
targetLabel := rc.TargetLabel
|
targetLabel := rc.TargetLabel
|
||||||
regexCompiled := defaultRegexForRelabelConfig
|
regexCompiled := defaultRegexForRelabelConfig
|
||||||
|
regexOriginalCompiled := defaultOriginalRegexForRelabelConfig
|
||||||
if rc.Regex != nil {
|
if rc.Regex != nil {
|
||||||
regex := *rc.Regex
|
regex := *rc.Regex
|
||||||
if rc.Action != "replace_all" && rc.Action != "labelmap_all" {
|
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)
|
re, err := regexp.Compile(regex)
|
||||||
if err != nil {
|
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
|
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
|
modulus := rc.Modulus
|
||||||
replacement := "$1"
|
replacement := "$1"
|
||||||
|
@ -85,49 +131,49 @@ func parseRelabelConfig(dst []ParsedRelabelConfig, rc *RelabelConfig) ([]ParsedR
|
||||||
switch action {
|
switch action {
|
||||||
case "replace":
|
case "replace":
|
||||||
if targetLabel == "" {
|
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":
|
case "replace_all":
|
||||||
if len(sourceLabels) == 0 {
|
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 == "" {
|
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":
|
case "keep_if_equal":
|
||||||
if len(sourceLabels) < 2 {
|
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":
|
case "drop_if_equal":
|
||||||
if len(sourceLabels) < 2 {
|
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":
|
case "keep":
|
||||||
if len(sourceLabels) == 0 {
|
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":
|
case "drop":
|
||||||
if len(sourceLabels) == 0 {
|
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":
|
case "hashmod":
|
||||||
if len(sourceLabels) == 0 {
|
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 == "" {
|
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 {
|
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":
|
||||||
case "labelmap_all":
|
case "labelmap_all":
|
||||||
case "labeldrop":
|
case "labeldrop":
|
||||||
case "labelkeep":
|
case "labelkeep":
|
||||||
default:
|
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,
|
SourceLabels: sourceLabels,
|
||||||
Separator: separator,
|
Separator: separator,
|
||||||
TargetLabel: targetLabel,
|
TargetLabel: targetLabel,
|
||||||
|
@ -136,8 +182,8 @@ func parseRelabelConfig(dst []ParsedRelabelConfig, rc *RelabelConfig) ([]ParsedR
|
||||||
Replacement: replacement,
|
Replacement: replacement,
|
||||||
Action: action,
|
Action: action,
|
||||||
|
|
||||||
|
regexOriginal: regexOriginalCompiled,
|
||||||
hasCaptureGroupInTargetLabel: strings.Contains(targetLabel, "$"),
|
hasCaptureGroupInTargetLabel: strings.Contains(targetLabel, "$"),
|
||||||
hasCaptureGroupInReplacement: strings.Contains(replacement, "$"),
|
hasCaptureGroupInReplacement: strings.Contains(replacement, "$"),
|
||||||
})
|
}, nil
|
||||||
return dst, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,12 @@ import (
|
||||||
|
|
||||||
func TestLoadRelabelConfigsSuccess(t *testing.T) {
|
func TestLoadRelabelConfigsSuccess(t *testing.T) {
|
||||||
path := "testdata/relabel_configs_valid.yml"
|
path := "testdata/relabel_configs_valid.yml"
|
||||||
prcs, err := LoadRelabelConfigs(path)
|
pcs, err := LoadRelabelConfigs(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("cannot load relabel configs from %q: %s", path, err)
|
t.Fatalf("cannot load relabel configs from %q: %s", path, err)
|
||||||
}
|
}
|
||||||
if len(prcs) != 9 {
|
if n := pcs.Len(); n != 9 {
|
||||||
t.Fatalf("unexpected number of relabel configs loaded from %q; got %d; want %d", path, len(prcs), 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 {
|
if err == nil {
|
||||||
t.Fatalf("expecting non-nil error")
|
t.Fatalf("expecting non-nil error")
|
||||||
}
|
}
|
||||||
if len(rcs) != 0 {
|
if rcs.Len() != 0 {
|
||||||
t.Fatalf("unexpected non-empty rcs: %#v", rcs)
|
t.Fatalf("unexpected non-empty rcs: %#v", rcs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,14 +36,14 @@ func TestLoadRelabelConfigsFailure(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseRelabelConfigsSuccess(t *testing.T) {
|
func TestParseRelabelConfigsSuccess(t *testing.T) {
|
||||||
f := func(rcs []RelabelConfig, prcsExpected []ParsedRelabelConfig) {
|
f := func(rcs []RelabelConfig, pcsExpected *ParsedConfigs) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
prcs, err := ParseRelabelConfigs(nil, rcs)
|
pcs, err := ParseRelabelConfigs(rcs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexected error: %s", err)
|
t.Fatalf("unexected error: %s", err)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(prcs, prcsExpected) {
|
if !reflect.DeepEqual(pcs, pcsExpected) {
|
||||||
t.Fatalf("unexpected prcs; got\n%#v\nwant\n%#v", prcs, prcsExpected)
|
t.Fatalf("unexpected pcs; got\n%#v\nwant\n%#v", pcs, pcsExpected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f(nil, nil)
|
f(nil, nil)
|
||||||
|
@ -52,16 +52,19 @@ func TestParseRelabelConfigsSuccess(t *testing.T) {
|
||||||
SourceLabels: []string{"foo", "bar"},
|
SourceLabels: []string{"foo", "bar"},
|
||||||
TargetLabel: "xxx",
|
TargetLabel: "xxx",
|
||||||
},
|
},
|
||||||
}, []ParsedRelabelConfig{
|
}, &ParsedConfigs{
|
||||||
{
|
prcs: []*parsedRelabelConfig{
|
||||||
SourceLabels: []string{"foo", "bar"},
|
{
|
||||||
Separator: ";",
|
SourceLabels: []string{"foo", "bar"},
|
||||||
TargetLabel: "xxx",
|
Separator: ";",
|
||||||
Regex: defaultRegexForRelabelConfig,
|
TargetLabel: "xxx",
|
||||||
Replacement: "$1",
|
Regex: defaultRegexForRelabelConfig,
|
||||||
Action: "replace",
|
Replacement: "$1",
|
||||||
|
Action: "replace",
|
||||||
|
|
||||||
hasCaptureGroupInReplacement: true,
|
regexOriginal: defaultOriginalRegexForRelabelConfig,
|
||||||
|
hasCaptureGroupInReplacement: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -69,12 +72,12 @@ func TestParseRelabelConfigsSuccess(t *testing.T) {
|
||||||
func TestParseRelabelConfigsFailure(t *testing.T) {
|
func TestParseRelabelConfigsFailure(t *testing.T) {
|
||||||
f := func(rcs []RelabelConfig) {
|
f := func(rcs []RelabelConfig) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
prcs, err := ParseRelabelConfigs(nil, rcs)
|
pcs, err := ParseRelabelConfigs(rcs)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("expecting non-nil error")
|
t.Fatalf("expecting non-nil error")
|
||||||
}
|
}
|
||||||
if len(prcs) > 0 {
|
if pcs.Len() > 0 {
|
||||||
t.Fatalf("unexpected non-empty prcs: %#v", prcs)
|
t.Fatalf("unexpected non-empty pcs: %#v", pcs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Run("invalid-regex", func(t *testing.T) {
|
t.Run("invalid-regex", func(t *testing.T) {
|
||||||
|
|
|
@ -12,10 +12,10 @@ import (
|
||||||
xxhash "github.com/cespare/xxhash/v2"
|
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
|
// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
|
||||||
type ParsedRelabelConfig struct {
|
type parsedRelabelConfig struct {
|
||||||
SourceLabels []string
|
SourceLabels []string
|
||||||
Separator string
|
Separator string
|
||||||
TargetLabel string
|
TargetLabel string
|
||||||
|
@ -24,29 +24,32 @@ type ParsedRelabelConfig struct {
|
||||||
Replacement string
|
Replacement string
|
||||||
Action string
|
Action string
|
||||||
|
|
||||||
|
regexOriginal *regexp.Regexp
|
||||||
hasCaptureGroupInTargetLabel bool
|
hasCaptureGroupInTargetLabel bool
|
||||||
hasCaptureGroupInReplacement bool
|
hasCaptureGroupInReplacement bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns human-readable representation for prc.
|
// 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",
|
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)
|
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:].
|
// If isFinalize is set, then FinalizeLabels is called on the labels[labelsOffset:].
|
||||||
//
|
//
|
||||||
// The returned labels at labels[labelsOffset:] are sorted.
|
// The returned labels at labels[labelsOffset:] are sorted.
|
||||||
func ApplyRelabelConfigs(labels []prompbmarshal.Label, labelsOffset int, prcs []ParsedRelabelConfig, isFinalize bool) []prompbmarshal.Label {
|
func (pcs *ParsedConfigs) Apply(labels []prompbmarshal.Label, labelsOffset int, isFinalize bool) []prompbmarshal.Label {
|
||||||
for i := range prcs {
|
if pcs != nil {
|
||||||
tmp := applyRelabelConfig(labels, labelsOffset, &prcs[i])
|
for _, prc := range pcs.prcs {
|
||||||
if len(tmp) == labelsOffset {
|
tmp := prc.apply(labels, labelsOffset)
|
||||||
// All the labels have been removed.
|
if len(tmp) == labelsOffset {
|
||||||
return tmp
|
// All the labels have been removed.
|
||||||
|
return tmp
|
||||||
|
}
|
||||||
|
labels = tmp
|
||||||
}
|
}
|
||||||
labels = tmp
|
|
||||||
}
|
}
|
||||||
labels = removeEmptyLabels(labels, labelsOffset)
|
labels = removeEmptyLabels(labels, labelsOffset)
|
||||||
if isFinalize {
|
if isFinalize {
|
||||||
|
@ -106,10 +109,10 @@ func FinalizeLabels(dst, src []prompbmarshal.Label) []prompbmarshal.Label {
|
||||||
return dst
|
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
|
// 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:]
|
src := labels[labelsOffset:]
|
||||||
switch prc.Action {
|
switch prc.Action {
|
||||||
case "replace":
|
case "replace":
|
||||||
|
@ -150,22 +153,13 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
||||||
case "replace_all":
|
case "replace_all":
|
||||||
bb := relabelBufPool.Get()
|
bb := relabelBufPool.Get()
|
||||||
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete && !prc.hasCaptureGroupInReplacement {
|
sourceStr := string(bb.B)
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
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)
|
relabelBufPool.Put(bb)
|
||||||
valueStr := prc.Regex.ReplaceAllString(sourceStr, prc.Replacement)
|
valueStr, ok := prc.replaceStringSubmatches(sourceStr, prc.Replacement, prc.hasCaptureGroupInReplacement)
|
||||||
return setLabelValue(labels, labelsOffset, prc.TargetLabel, valueStr)
|
if ok {
|
||||||
|
labels = setLabelValue(labels, labelsOffset, prc.TargetLabel, valueStr)
|
||||||
|
}
|
||||||
|
return labels
|
||||||
case "keep_if_equal":
|
case "keep_if_equal":
|
||||||
// Keep the entry if all the label values in source_labels are equal.
|
// Keep the entry if all the label values in source_labels are equal.
|
||||||
// For example:
|
// For example:
|
||||||
|
@ -193,14 +187,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
||||||
case "keep":
|
case "keep":
|
||||||
bb := relabelBufPool.Get()
|
bb := relabelBufPool.Get()
|
||||||
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||||
keep := false
|
keep := prc.matchString(bytesutil.ToUnsafeString(bb.B))
|
||||||
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)
|
|
||||||
}
|
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
if !keep {
|
if !keep {
|
||||||
return labels[:labelsOffset]
|
return labels[:labelsOffset]
|
||||||
|
@ -209,14 +196,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
||||||
case "drop":
|
case "drop":
|
||||||
bb := relabelBufPool.Get()
|
bb := relabelBufPool.Get()
|
||||||
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
bb.B = concatLabelValues(bb.B[:0], src, prc.SourceLabels, prc.Separator)
|
||||||
drop := false
|
drop := prc.matchString(bytesutil.ToUnsafeString(bb.B))
|
||||||
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)
|
|
||||||
}
|
|
||||||
relabelBufPool.Put(bb)
|
relabelBufPool.Put(bb)
|
||||||
if drop {
|
if drop {
|
||||||
return labels[:labelsOffset]
|
return labels[:labelsOffset]
|
||||||
|
@ -232,42 +212,23 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
||||||
case "labelmap":
|
case "labelmap":
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
match := prc.Regex.FindStringSubmatchIndex(label.Name)
|
labelName, ok := prc.replaceFullString(label.Name, prc.Replacement, prc.hasCaptureGroupInReplacement)
|
||||||
if match == nil {
|
if ok {
|
||||||
continue
|
labels = setLabelValue(labels, labelsOffset, labelName, label.Value)
|
||||||
}
|
}
|
||||||
value := relabelBufPool.Get()
|
|
||||||
value.B = prc.Regex.ExpandString(value.B[:0], prc.Replacement, label.Name, match)
|
|
||||||
labelName := string(value.B)
|
|
||||||
relabelBufPool.Put(value)
|
|
||||||
labels = setLabelValue(labels, labelsOffset, labelName, label.Value)
|
|
||||||
}
|
}
|
||||||
return labels
|
return labels
|
||||||
case "labelmap_all":
|
case "labelmap_all":
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete && !prc.hasCaptureGroupInReplacement {
|
label.Name, _ = prc.replaceStringSubmatches(label.Name, prc.Replacement, 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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return labels
|
return labels
|
||||||
case "labeldrop":
|
case "labeldrop":
|
||||||
keepSrc := true
|
keepSrc := true
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
if prc.matchString(label.Name) {
|
||||||
if prefix == label.Name {
|
|
||||||
keepSrc = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if prc.Regex.MatchString(label.Name) {
|
|
||||||
keepSrc = false
|
keepSrc = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -278,11 +239,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
||||||
dst := labels[:labelsOffset]
|
dst := labels[:labelsOffset]
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
if !prc.matchString(label.Name) {
|
||||||
if prefix != label.Name {
|
|
||||||
dst = append(dst, *label)
|
|
||||||
}
|
|
||||||
} else if !prc.Regex.MatchString(label.Name) {
|
|
||||||
dst = append(dst, *label)
|
dst = append(dst, *label)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,12 +248,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
||||||
keepSrc := true
|
keepSrc := true
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
if !prc.matchString(label.Name) {
|
||||||
if prefix != label.Name {
|
|
||||||
keepSrc = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else if !prc.Regex.MatchString(src[i].Name) {
|
|
||||||
keepSrc = false
|
keepSrc = false
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -307,11 +259,7 @@ func applyRelabelConfig(labels []prompbmarshal.Label, labelsOffset int, prc *Par
|
||||||
dst := labels[:labelsOffset]
|
dst := labels[:labelsOffset]
|
||||||
for i := range src {
|
for i := range src {
|
||||||
label := &src[i]
|
label := &src[i]
|
||||||
if prefix, complete := prc.Regex.LiteralPrefix(); complete {
|
if prc.matchString(label.Name) {
|
||||||
if prefix == label.Name {
|
|
||||||
dst = append(dst, *label)
|
|
||||||
}
|
|
||||||
} else if prc.Regex.MatchString(label.Name) {
|
|
||||||
dst = append(dst, *label)
|
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 := relabelBufPool.Get()
|
||||||
bb.B = prc.Regex.ExpandString(bb.B[:0], template, source, match)
|
bb.B = prc.Regex.ExpandString(bb.B[:0], template, source, match)
|
||||||
s := string(bb.B)
|
s := string(bb.B)
|
||||||
|
|
|
@ -2,24 +2,27 @@ package promrelabel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestApplyRelabelConfigs(t *testing.T) {
|
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()
|
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) {
|
if !reflect.DeepEqual(result, resultExpected) {
|
||||||
t.Fatalf("unexpected result; got\n%v\nwant\n%v", result, resultExpected)
|
t.Fatalf("unexpected result; got\n%v\nwant\n%v", result, resultExpected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Run("empty_relabel_configs", func(t *testing.T) {
|
t.Run("empty_relabel_configs", func(t *testing.T) {
|
||||||
f(nil, nil, false, nil)
|
f("", nil, false, nil)
|
||||||
f(nil, nil, true, nil)
|
f("", nil, true, nil)
|
||||||
f(nil, []prompbmarshal.Label{
|
f("", []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
|
@ -30,7 +33,7 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
f(nil, []prompbmarshal.Label{
|
f("", []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
|
@ -55,35 +58,20 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("replace-miss", func(t *testing.T) {
|
t.Run("replace-miss", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
target_label: bar
|
||||||
TargetLabel: "bar",
|
`, nil, false, []prompbmarshal.Label{})
|
||||||
Regex: defaultRegexForRelabelConfig,
|
f(`
|
||||||
Replacement: "$1",
|
- action: replace
|
||||||
hasCaptureGroupInReplacement: true,
|
source_labels: ["foo"]
|
||||||
},
|
target_label: bar
|
||||||
}, nil, false, []prompbmarshal.Label{})
|
`, nil, false, []prompbmarshal.Label{})
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
source_labels: ["foo"]
|
||||||
SourceLabels: []string{"foo"},
|
target_label: "bar"
|
||||||
TargetLabel: "bar",
|
`, []prompbmarshal.Label{
|
||||||
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{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -94,16 +82,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
source_labels: ["foo"]
|
||||||
SourceLabels: []string{"foo"},
|
target_label: "bar"
|
||||||
TargetLabel: "bar",
|
regex: ".+"
|
||||||
Regex: regexp.MustCompile(".+"),
|
`, []prompbmarshal.Label{
|
||||||
Replacement: "$1",
|
|
||||||
hasCaptureGroupInReplacement: true,
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -116,17 +100,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("replace-hit", func(t *testing.T) {
|
t.Run("replace-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
source_labels: ["xxx", "foo"]
|
||||||
SourceLabels: []string{"xxx", "foo"},
|
target_label: "bar"
|
||||||
Separator: ";",
|
replacement: "a-$1-b"
|
||||||
TargetLabel: "bar",
|
`, []prompbmarshal.Label{
|
||||||
Regex: defaultRegexForRelabelConfig,
|
|
||||||
Replacement: "a-$1-b",
|
|
||||||
hasCaptureGroupInReplacement: true,
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -143,18 +122,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("replace-hit-target-label-with-capture-group", func(t *testing.T) {
|
t.Run("replace-hit-target-label-with-capture-group", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
source_labels: ["xxx", "foo"]
|
||||||
SourceLabels: []string{"xxx", "foo"},
|
target_label: "bar-$1"
|
||||||
Separator: ";",
|
replacement: "a-$1-b"
|
||||||
TargetLabel: "bar-$1",
|
`, []prompbmarshal.Label{
|
||||||
Regex: defaultRegexForRelabelConfig,
|
|
||||||
Replacement: "a-$1-b",
|
|
||||||
hasCaptureGroupInTargetLabel: true,
|
|
||||||
hasCaptureGroupInReplacement: true,
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -171,35 +144,21 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("replace_all-miss", func(t *testing.T) {
|
t.Run("replace_all-miss", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace_all
|
||||||
Action: "replace_all",
|
source_labels: [foo]
|
||||||
TargetLabel: "bar",
|
target_label: "bar"
|
||||||
Regex: defaultRegexForRelabelConfig,
|
`, nil, false, []prompbmarshal.Label{})
|
||||||
Replacement: "$1",
|
f(`
|
||||||
hasCaptureGroupInReplacement: true,
|
- action: replace_all
|
||||||
},
|
source_labels: ["foo"]
|
||||||
}, nil, false, []prompbmarshal.Label{})
|
target_label: "bar"
|
||||||
f([]ParsedRelabelConfig{
|
`, nil, false, []prompbmarshal.Label{})
|
||||||
{
|
f(`
|
||||||
Action: "replace_all",
|
- action: replace_all
|
||||||
SourceLabels: []string{"foo"},
|
source_labels: ["foo"]
|
||||||
TargetLabel: "bar",
|
target_label: "bar"
|
||||||
Regex: defaultRegexForRelabelConfig,
|
`, []prompbmarshal.Label{
|
||||||
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{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -210,16 +169,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace_all
|
||||||
Action: "replace_all",
|
source_labels: ["foo"]
|
||||||
SourceLabels: []string{"foo"},
|
target_label: "bar"
|
||||||
TargetLabel: "bar",
|
regex: ".+"
|
||||||
Regex: regexp.MustCompile(".+"),
|
`, []prompbmarshal.Label{
|
||||||
Replacement: "$1",
|
|
||||||
hasCaptureGroupInReplacement: true,
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -232,16 +187,13 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("replace_all-hit", func(t *testing.T) {
|
t.Run("replace_all-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace_all
|
||||||
Action: "replace_all",
|
source_labels: ["xxx"]
|
||||||
SourceLabels: []string{"xxx"},
|
target_label: "xxx"
|
||||||
Separator: ";",
|
regex: "-"
|
||||||
TargetLabel: "xxx",
|
replacement: "."
|
||||||
Regex: regexp.MustCompile("-"),
|
`, []prompbmarshal.Label{
|
||||||
Replacement: ".",
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "a-b-c",
|
Value: "a-b-c",
|
||||||
|
@ -254,17 +206,13 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("replace_all-regex-hit", func(t *testing.T) {
|
t.Run("replace_all-regex-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace_all
|
||||||
Action: "replace_all",
|
source_labels: ["xxx", "foo"]
|
||||||
SourceLabels: []string{"xxx", "foo"},
|
target_label: "xxx"
|
||||||
Separator: ";",
|
regex: "(;)"
|
||||||
TargetLabel: "xxx",
|
replacement: "-$1-"
|
||||||
Regex: regexp.MustCompile("(;)"),
|
`, []prompbmarshal.Label{
|
||||||
Replacement: "-$1-",
|
|
||||||
hasCaptureGroupInReplacement: true,
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "y;y",
|
Value: "y;y",
|
||||||
|
@ -277,24 +225,16 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("replace-add-multi-labels", func(t *testing.T) {
|
t.Run("replace-add-multi-labels", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
source_labels: ["xxx"]
|
||||||
SourceLabels: []string{"xxx"},
|
target_label: "bar"
|
||||||
TargetLabel: "bar",
|
replacement: "a-$1"
|
||||||
Regex: defaultRegexForRelabelConfig,
|
- action: replace
|
||||||
Replacement: "a-$1",
|
source_labels: ["bar"]
|
||||||
hasCaptureGroupInReplacement: true,
|
target_label: "zar"
|
||||||
},
|
replacement: "b-$1"
|
||||||
{
|
`, []prompbmarshal.Label{
|
||||||
Action: "replace",
|
|
||||||
SourceLabels: []string{"bar"},
|
|
||||||
TargetLabel: "zar",
|
|
||||||
Regex: defaultRegexForRelabelConfig,
|
|
||||||
Replacement: "b-$1",
|
|
||||||
hasCaptureGroupInReplacement: true,
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -323,16 +263,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("replace-self", func(t *testing.T) {
|
t.Run("replace-self", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
source_labels: ["foo"]
|
||||||
SourceLabels: []string{"foo"},
|
target_label: "foo"
|
||||||
TargetLabel: "foo",
|
replacement: "a-$1"
|
||||||
Regex: defaultRegexForRelabelConfig,
|
`, []prompbmarshal.Label{
|
||||||
Replacement: "a-$1",
|
|
||||||
hasCaptureGroupInReplacement: true,
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "aaxx",
|
Value: "aaxx",
|
||||||
|
@ -345,14 +281,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("replace-missing-source", func(t *testing.T) {
|
t.Run("replace-missing-source", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
target_label: foo
|
||||||
TargetLabel: "foo",
|
replacement: "foobar"
|
||||||
Regex: defaultRegexForRelabelConfig,
|
`, []prompbmarshal.Label{}, true, []prompbmarshal.Label{
|
||||||
Replacement: "foobar",
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{}, true, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "foobar",
|
Value: "foobar",
|
||||||
|
@ -360,18 +293,14 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("keep_if_equal-miss", func(t *testing.T) {
|
t.Run("keep_if_equal-miss", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: keep_if_equal
|
||||||
Action: "keep_if_equal",
|
source_labels: ["foo", "bar"]
|
||||||
SourceLabels: []string{"foo", "bar"},
|
`, nil, true, nil)
|
||||||
},
|
f(`
|
||||||
}, nil, true, nil)
|
- action: keep_if_equal
|
||||||
f([]ParsedRelabelConfig{
|
source_labels: ["xxx", "bar"]
|
||||||
{
|
`, []prompbmarshal.Label{
|
||||||
Action: "keep_if_equal",
|
|
||||||
SourceLabels: []string{"xxx", "bar"},
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -379,12 +308,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
}, true, []prompbmarshal.Label{})
|
}, true, []prompbmarshal.Label{})
|
||||||
})
|
})
|
||||||
t.Run("keep_if_equal-hit", func(t *testing.T) {
|
t.Run("keep_if_equal-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: keep_if_equal
|
||||||
Action: "keep_if_equal",
|
source_labels: ["xxx", "bar"]
|
||||||
SourceLabels: []string{"xxx", "bar"},
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -405,18 +332,14 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("drop_if_equal-miss", func(t *testing.T) {
|
t.Run("drop_if_equal-miss", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: drop_if_equal
|
||||||
Action: "drop_if_equal",
|
source_labels: ["foo", "bar"]
|
||||||
SourceLabels: []string{"foo", "bar"},
|
`, nil, true, nil)
|
||||||
},
|
f(`
|
||||||
}, nil, true, nil)
|
- action: drop_if_equal
|
||||||
f([]ParsedRelabelConfig{
|
source_labels: ["xxx", "bar"]
|
||||||
{
|
`, []prompbmarshal.Label{
|
||||||
Action: "drop_if_equal",
|
|
||||||
SourceLabels: []string{"xxx", "bar"},
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -429,12 +352,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("drop_if_equal-hit", func(t *testing.T) {
|
t.Run("drop_if_equal-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: drop_if_equal
|
||||||
Action: "drop_if_equal",
|
source_labels: [xxx, bar]
|
||||||
SourceLabels: []string{"xxx", "bar"},
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -446,20 +367,16 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
}, true, []prompbmarshal.Label{})
|
}, true, []prompbmarshal.Label{})
|
||||||
})
|
})
|
||||||
t.Run("keep-miss", func(t *testing.T) {
|
t.Run("keep-miss", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: keep
|
||||||
Action: "keep",
|
source_labels: [foo]
|
||||||
SourceLabels: []string{"foo"},
|
regex: ".+"
|
||||||
Regex: regexp.MustCompile(".+"),
|
`, nil, true, nil)
|
||||||
},
|
f(`
|
||||||
}, nil, true, nil)
|
- action: keep
|
||||||
f([]ParsedRelabelConfig{
|
source_labels: [foo]
|
||||||
{
|
regex: ".+"
|
||||||
Action: "keep",
|
`, []prompbmarshal.Label{
|
||||||
SourceLabels: []string{"foo"},
|
|
||||||
Regex: regexp.MustCompile(".+"),
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -467,13 +384,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
}, true, []prompbmarshal.Label{})
|
}, true, []prompbmarshal.Label{})
|
||||||
})
|
})
|
||||||
t.Run("keep-hit", func(t *testing.T) {
|
t.Run("keep-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: keep
|
||||||
Action: "keep",
|
source_labels: [foo]
|
||||||
SourceLabels: []string{"foo"},
|
regex: "yyy"
|
||||||
Regex: regexp.MustCompile("yyy"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -486,13 +401,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("keep-hit-regexp", func(t *testing.T) {
|
t.Run("keep-hit-regexp", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: keep
|
||||||
Action: "keep",
|
source_labels: ["foo"]
|
||||||
SourceLabels: []string{"foo"},
|
regex: ".+"
|
||||||
Regex: regexp.MustCompile(".+"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -505,20 +418,16 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("drop-miss", func(t *testing.T) {
|
t.Run("drop-miss", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: drop
|
||||||
Action: "drop",
|
source_labels: [foo]
|
||||||
SourceLabels: []string{"foo"},
|
regex: ".+"
|
||||||
Regex: regexp.MustCompile(".+"),
|
`, nil, false, nil)
|
||||||
},
|
f(`
|
||||||
}, nil, false, nil)
|
- action: drop
|
||||||
f([]ParsedRelabelConfig{
|
source_labels: [foo]
|
||||||
{
|
regex: ".+"
|
||||||
Action: "drop",
|
`, []prompbmarshal.Label{
|
||||||
SourceLabels: []string{"foo"},
|
|
||||||
Regex: regexp.MustCompile(".+"),
|
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -531,13 +440,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("drop-hit", func(t *testing.T) {
|
t.Run("drop-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: drop
|
||||||
Action: "drop",
|
source_labels: [foo]
|
||||||
SourceLabels: []string{"foo"},
|
regex: yyy
|
||||||
Regex: regexp.MustCompile("yyy"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -545,13 +452,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
}, true, []prompbmarshal.Label{})
|
}, true, []prompbmarshal.Label{})
|
||||||
})
|
})
|
||||||
t.Run("drop-hit-regexp", func(t *testing.T) {
|
t.Run("drop-hit-regexp", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: drop
|
||||||
Action: "drop",
|
source_labels: [foo]
|
||||||
SourceLabels: []string{"foo"},
|
regex: ".+"
|
||||||
Regex: regexp.MustCompile(".+"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -559,14 +464,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
}, true, []prompbmarshal.Label{})
|
}, true, []prompbmarshal.Label{})
|
||||||
})
|
})
|
||||||
t.Run("hashmod-miss", func(t *testing.T) {
|
t.Run("hashmod-miss", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: hashmod
|
||||||
Action: "hashmod",
|
source_labels: [foo]
|
||||||
SourceLabels: []string{"foo"},
|
target_label: aaa
|
||||||
TargetLabel: "aaa",
|
modulus: 123
|
||||||
Modulus: 123,
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -583,14 +486,12 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("hashmod-hit", func(t *testing.T) {
|
t.Run("hashmod-hit", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: hashmod
|
||||||
Action: "hashmod",
|
source_labels: [foo]
|
||||||
SourceLabels: []string{"foo"},
|
target_label: aaa
|
||||||
TargetLabel: "aaa",
|
modulus: 123
|
||||||
Modulus: 123,
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -606,14 +507,97 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("labelmap", func(t *testing.T) {
|
t.Run("labelmap-copy-label", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
|
- action: labelmap
|
||||||
|
regex: "foo"
|
||||||
|
replacement: "bar"
|
||||||
|
`, []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Action: "labelmap",
|
Name: "foo",
|
||||||
Regex: regexp.MustCompile("foo(.+)"),
|
Value: "yyy",
|
||||||
Replacement: "$1-x",
|
|
||||||
},
|
},
|
||||||
}, []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",
|
Name: "foo",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -638,13 +622,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("labelmap_all", func(t *testing.T) {
|
t.Run("labelmap_all", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labelmap_all
|
||||||
Action: "labelmap_all",
|
regex: "\\."
|
||||||
Regex: regexp.MustCompile(`\.`),
|
replacement: "-"
|
||||||
Replacement: "-",
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "foo.bar.baz",
|
Name: "foo.bar.baz",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -665,13 +647,11 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("labelmap_all-regexp", func(t *testing.T) {
|
t.Run("labelmap_all-regexp", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labelmap_all
|
||||||
Action: "labelmap_all",
|
regex: "ba(.)"
|
||||||
Regex: regexp.MustCompile(`ba(.)`),
|
replacement: "${1}ss"
|
||||||
Replacement: "${1}ss",
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "foo.bar.baz",
|
Name: "foo.bar.baz",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -692,12 +672,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("labeldrop", func(t *testing.T) {
|
t.Run("labeldrop", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labeldrop
|
||||||
Action: "labeldrop",
|
regex: dropme
|
||||||
Regex: regexp.MustCompile("dropme"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "aaa",
|
Name: "aaa",
|
||||||
Value: "bbb",
|
Value: "bbb",
|
||||||
|
@ -708,12 +686,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
Value: "bbb",
|
Value: "bbb",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labeldrop
|
||||||
Action: "labeldrop",
|
regex: dropme
|
||||||
Regex: regexp.MustCompile("dropme"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -738,12 +714,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("labeldrop-regexp", func(t *testing.T) {
|
t.Run("labeldrop-regexp", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labeldrop
|
||||||
Action: "labeldrop",
|
regex: "dropme.*"
|
||||||
Regex: regexp.MustCompile("dropme.*"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "aaa",
|
Name: "aaa",
|
||||||
Value: "bbb",
|
Value: "bbb",
|
||||||
|
@ -754,12 +728,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
Value: "bbb",
|
Value: "bbb",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labeldrop
|
||||||
Action: "labeldrop",
|
regex: "dropme.*"
|
||||||
Regex: regexp.MustCompile("dropme.*"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "xxx",
|
Name: "xxx",
|
||||||
Value: "yyy",
|
Value: "yyy",
|
||||||
|
@ -784,12 +756,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("labelkeep", func(t *testing.T) {
|
t.Run("labelkeep", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labelkeep
|
||||||
Action: "labelkeep",
|
regex: "keepme"
|
||||||
Regex: regexp.MustCompile("keepme"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "keepme",
|
Name: "keepme",
|
||||||
Value: "aaa",
|
Value: "aaa",
|
||||||
|
@ -800,12 +770,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
Value: "aaa",
|
Value: "aaa",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labelkeep
|
||||||
Action: "labelkeep",
|
regex: keepme
|
||||||
Regex: regexp.MustCompile("keepme"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "keepme",
|
Name: "keepme",
|
||||||
Value: "aaa",
|
Value: "aaa",
|
||||||
|
@ -826,12 +794,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
t.Run("labelkeep-regexp", func(t *testing.T) {
|
t.Run("labelkeep-regexp", func(t *testing.T) {
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labelkeep
|
||||||
Action: "labelkeep",
|
regex: "keepme.*"
|
||||||
Regex: regexp.MustCompile("keepme.*"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "keepme",
|
Name: "keepme",
|
||||||
Value: "aaa",
|
Value: "aaa",
|
||||||
|
@ -842,12 +808,10 @@ func TestApplyRelabelConfigs(t *testing.T) {
|
||||||
Value: "aaa",
|
Value: "aaa",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
f([]ParsedRelabelConfig{
|
f(`
|
||||||
{
|
- action: labelkeep
|
||||||
Action: "labelkeep",
|
regex: "keepme.*"
|
||||||
Regex: regexp.MustCompile("keepme.*"),
|
`, []prompbmarshal.Label{
|
||||||
},
|
|
||||||
}, []prompbmarshal.Label{
|
|
||||||
{
|
{
|
||||||
Name: "keepme",
|
Name: "keepme",
|
||||||
Value: "aaa",
|
Value: "aaa",
|
||||||
|
|
|
@ -2,7 +2,6 @@ package promrelabel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
||||||
|
@ -10,15 +9,11 @@ import (
|
||||||
|
|
||||||
func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
b.Run("replace-label-copy", func(b *testing.B) {
|
b.Run("replace-label-copy", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
source_labels: [id]
|
||||||
SourceLabels: []string{"id"},
|
target_label: __name__
|
||||||
TargetLabel: "__name__",
|
`)
|
||||||
Regex: defaultRegexForRelabelConfig,
|
|
||||||
Replacement: "$1",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -35,7 +30,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != len(labelsOrig) {
|
if len(labels) != len(labelsOrig) {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
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) {
|
b.Run("replace-set-label", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
target_label: __name__
|
||||||
TargetLabel: "__name__",
|
replacement: foobar
|
||||||
Regex: defaultRegexForRelabelConfig,
|
`)
|
||||||
Replacement: "foobar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -79,7 +71,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != len(labelsOrig) {
|
if len(labels) != len(labelsOrig) {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
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) {
|
b.Run("replace-add-label", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
target_label: aaa
|
||||||
TargetLabel: "aaa",
|
replacement: foobar
|
||||||
Regex: defaultRegexForRelabelConfig,
|
`)
|
||||||
Replacement: "foobar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -119,7 +108,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 2 {
|
if len(labels) != 2 {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 2, labels))
|
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) {
|
b.Run("replace-mismatch", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
source_labels: ["non-existing-label"]
|
||||||
SourceLabels: []string{"non-existing-label"},
|
target_label: id
|
||||||
TargetLabel: "id",
|
regex: "(foobar)-.*"
|
||||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
`)
|
||||||
Replacement: "$1",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -164,7 +150,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != len(labelsOrig) {
|
if len(labels) != len(labelsOrig) {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
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) {
|
b.Run("replace-match-regex", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: replace
|
||||||
Action: "replace",
|
source_labels: [id]
|
||||||
SourceLabels: []string{"id"},
|
target_label: id
|
||||||
TargetLabel: "id",
|
regex: "(foobar)-.*"
|
||||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
`)
|
||||||
Replacement: "$1",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -209,7 +192,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != len(labelsOrig) {
|
if len(labels) != len(labelsOrig) {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
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) {
|
b.Run("drop-mismatch", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: drop
|
||||||
Action: "drop",
|
source_labels: ["non-existing-label"]
|
||||||
SourceLabels: []string{"non-existing-label"},
|
regex: "(foobar)-.*"
|
||||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -252,7 +233,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != len(labelsOrig) {
|
if len(labels) != len(labelsOrig) {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
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) {
|
b.Run("drop-match", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: drop
|
||||||
Action: "drop",
|
source_labels: [id]
|
||||||
SourceLabels: []string{"id"},
|
regex: yes
|
||||||
Regex: regexp.MustCompile("yes"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -295,7 +274,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 0 {
|
if len(labels) != 0 {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels))
|
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) {
|
b.Run("drop-match-regexp", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: drop
|
||||||
Action: "drop",
|
source_labels: [id]
|
||||||
SourceLabels: []string{"id"},
|
regex: "(foobar)-.*"
|
||||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -326,7 +303,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 0 {
|
if len(labels) != 0 {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels))
|
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) {
|
b.Run("keep-mismatch", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: keep
|
||||||
Action: "keep",
|
source_labels: ["non-existing-label"]
|
||||||
SourceLabels: []string{"non-existing-label"},
|
regex: "(foobar)-.*"
|
||||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -357,7 +332,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 0 {
|
if len(labels) != 0 {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels))
|
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) {
|
b.Run("keep-match", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: keep
|
||||||
Action: "keep",
|
source_labels: [id]
|
||||||
SourceLabels: []string{"id"},
|
regex: yes
|
||||||
Regex: regexp.MustCompile("yes"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -388,7 +361,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != len(labelsOrig) {
|
if len(labels) != len(labelsOrig) {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
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) {
|
b.Run("keep-match-regexp", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: keep
|
||||||
Action: "keep",
|
source_labels: [id]
|
||||||
SourceLabels: []string{"id"},
|
regex: "(foobar)-.*"
|
||||||
Regex: regexp.MustCompile("(foobar)-.*"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -431,7 +402,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != len(labelsOrig) {
|
if len(labels) != len(labelsOrig) {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
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) {
|
b.Run("labeldrop-mismatch", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: labeldrop
|
||||||
Action: "labeldrop",
|
regex: "non-existing-label"
|
||||||
Regex: regexp.MustCompile("non-existing-label"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -473,7 +442,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != len(labelsOrig) {
|
if len(labels) != len(labelsOrig) {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
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) {
|
b.Run("labeldrop-match", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: labeldrop
|
||||||
Action: "labeldrop",
|
regex: id
|
||||||
Regex: regexp.MustCompile("id"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -515,7 +482,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 1 {
|
if len(labels) != 1 {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels))
|
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) {
|
b.Run("labeldrop-match-regexp", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: labeldrop
|
||||||
Action: "labeldrop",
|
regex: "id.*"
|
||||||
Regex: regexp.MustCompile("id.*"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -551,7 +516,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 1 {
|
if len(labels) != 1 {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels))
|
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) {
|
b.Run("labelkeep-mismatch", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: labelkeep
|
||||||
Action: "labelkeep",
|
regex: "non-existing-label"
|
||||||
Regex: regexp.MustCompile("non-existing-label"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -587,7 +550,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 0 {
|
if len(labels) != 0 {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels))
|
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) {
|
b.Run("labelkeep-match", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: labelkeep
|
||||||
Action: "labelkeep",
|
regex: id
|
||||||
Regex: regexp.MustCompile("id"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -617,7 +578,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 1 {
|
if len(labels) != 1 {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels))
|
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) {
|
b.Run("labelkeep-match-regexp", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: labelkeep
|
||||||
Action: "labelkeep",
|
regex: "id.*"
|
||||||
Regex: regexp.MustCompile("id.*"),
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -653,7 +612,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 1 {
|
if len(labels) != 1 {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels))
|
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) {
|
b.Run("labelmap-mismatch", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: labelmap
|
||||||
Action: "labelmap",
|
regex: "a(.*)"
|
||||||
Regex: regexp.MustCompile("a(.*)"),
|
`)
|
||||||
Replacement: "$1",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
|
||||||
Name: "aabc",
|
|
||||||
Value: "foobar-random-string-here",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Name: "foo",
|
Name: "foo",
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
|
@ -690,8 +642,38 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != 3 {
|
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))
|
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 3, labels))
|
||||||
}
|
}
|
||||||
if labels[0].Name != "aabc" {
|
if labels[0].Name != "aabc" {
|
||||||
|
@ -706,24 +688,52 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
if labels[1].Value != "foobar-random-string-here" {
|
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"))
|
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"))
|
})
|
||||||
|
})
|
||||||
|
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[2].Value != "bar" {
|
if labels[0].Name != "aa" {
|
||||||
panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[2].Value, "bar"))
|
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) {
|
b.Run("hashmod", func(b *testing.B) {
|
||||||
prcs := []ParsedRelabelConfig{
|
pcs := mustParseRelabelConfigs(`
|
||||||
{
|
- action: hashmod
|
||||||
Action: "hashmod",
|
source_labels: [id]
|
||||||
SourceLabels: []string{"id"},
|
target_label: id
|
||||||
TargetLabel: "id",
|
modulus: 23
|
||||||
Modulus: 23,
|
`)
|
||||||
},
|
|
||||||
}
|
|
||||||
labelsOrig := []prompbmarshal.Label{
|
labelsOrig := []prompbmarshal.Label{
|
||||||
{
|
{
|
||||||
Name: "__name__",
|
Name: "__name__",
|
||||||
|
@ -740,7 +750,7 @@ func BenchmarkApplyRelabelConfigs(b *testing.B) {
|
||||||
var labels []prompbmarshal.Label
|
var labels []prompbmarshal.Label
|
||||||
for pb.Next() {
|
for pb.Next() {
|
||||||
labels = append(labels[:0], labelsOrig...)
|
labels = append(labels[:0], labelsOrig...)
|
||||||
labels = ApplyRelabelConfigs(labels, 0, prcs, true)
|
labels = pcs.Apply(labels, 0, true)
|
||||||
if len(labels) != len(labelsOrig) {
|
if len(labels) != len(labelsOrig) {
|
||||||
panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels))
|
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 {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse auth config for `job_name` %q: %w", jobName, err)
|
return nil, fmt.Errorf("cannot parse auth config for `job_name` %q: %w", jobName, err)
|
||||||
}
|
}
|
||||||
var relabelConfigs []promrelabel.ParsedRelabelConfig
|
relabelConfigs, err := promrelabel.ParseRelabelConfigs(sc.RelabelConfigs)
|
||||||
relabelConfigs, err = promrelabel.ParseRelabelConfigs(relabelConfigs[:0], sc.RelabelConfigs)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse `relabel_configs` for `job_name` %q: %w", jobName, err)
|
return nil, fmt.Errorf("cannot parse `relabel_configs` for `job_name` %q: %w", jobName, err)
|
||||||
}
|
}
|
||||||
var metricRelabelConfigs []promrelabel.ParsedRelabelConfig
|
metricRelabelConfigs, err := promrelabel.ParseRelabelConfigs(sc.MetricRelabelConfigs)
|
||||||
metricRelabelConfigs, err = promrelabel.ParseRelabelConfigs(metricRelabelConfigs[:0], sc.MetricRelabelConfigs)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse `metric_relabel_configs` for `job_name` %q: %w", jobName, err)
|
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
|
honorLabels bool
|
||||||
honorTimestamps bool
|
honorTimestamps bool
|
||||||
externalLabels map[string]string
|
externalLabels map[string]string
|
||||||
relabelConfigs []promrelabel.ParsedRelabelConfig
|
relabelConfigs *promrelabel.ParsedConfigs
|
||||||
metricRelabelConfigs []promrelabel.ParsedRelabelConfig
|
metricRelabelConfigs *promrelabel.ParsedConfigs
|
||||||
sampleLimit int
|
sampleLimit int
|
||||||
disableCompression bool
|
disableCompression bool
|
||||||
disableKeepAlive 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.
|
// Reduce memory usage by interning all the strings in originalLabels.
|
||||||
internLabelStrings(originalLabels)
|
internLabelStrings(originalLabels)
|
||||||
}
|
}
|
||||||
labels = promrelabel.ApplyRelabelConfigs(labels, 0, swc.relabelConfigs, false)
|
labels = swc.relabelConfigs.Apply(labels, 0, false)
|
||||||
labels = promrelabel.RemoveMetaLabels(labels[:0], labels)
|
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).
|
// 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.
|
// 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"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promauth"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/promrelabel"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLoadStaticConfigs(t *testing.T) {
|
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(`
|
f(`
|
||||||
scrape_configs:
|
scrape_configs:
|
||||||
- job_name: foo
|
- job_name: foo
|
||||||
|
@ -1076,9 +1067,12 @@ scrape_configs:
|
||||||
Value: "foo",
|
Value: "foo",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
AuthConfig: &promauth.Config{},
|
AuthConfig: &promauth.Config{},
|
||||||
MetricRelabelConfigs: prcs,
|
MetricRelabelConfigs: mustParseRelabelConfigs(`
|
||||||
jobNameOriginal: "foo",
|
- source_labels: [foo]
|
||||||
|
target_label: abc
|
||||||
|
`),
|
||||||
|
jobNameOriginal: "foo",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
f(`
|
f(`
|
||||||
|
@ -1374,8 +1368,6 @@ scrape_configs:
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var defaultRegexForRelabelConfig = regexp.MustCompile("^(.*)$")
|
|
||||||
|
|
||||||
func equalStaticConfigForScrapeWorks(a, b []*ScrapeWork) bool {
|
func equalStaticConfigForScrapeWorks(a, b []*ScrapeWork) bool {
|
||||||
if len(a) != len(b) {
|
if len(a) != len(b) {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -76,7 +75,7 @@ type ScrapeWork struct {
|
||||||
ProxyURL proxy.URL
|
ProxyURL proxy.URL
|
||||||
|
|
||||||
// Optional `metric_relabel_configs`.
|
// Optional `metric_relabel_configs`.
|
||||||
MetricRelabelConfigs []promrelabel.ParsedRelabelConfig
|
MetricRelabelConfigs *promrelabel.ParsedConfigs
|
||||||
|
|
||||||
// The maximum number of metrics to scrape after relabeling.
|
// The maximum number of metrics to scrape after relabeling.
|
||||||
SampleLimit int
|
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, "+
|
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",
|
"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.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
|
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
|
// Job returns job for the ScrapeWork
|
||||||
func (sw *ScrapeWork) Job() string {
|
func (sw *ScrapeWork) Job() string {
|
||||||
return promrelabel.GetLabelValueByName(sw.Labels, "job")
|
return promrelabel.GetLabelValueByName(sw.Labels, "job")
|
||||||
|
@ -503,7 +494,7 @@ func (sw *scrapeWork) addRowToTimeseries(wc *writeRequestCtx, r *parser.Row, tim
|
||||||
labelsLen := len(wc.labels)
|
labelsLen := len(wc.labels)
|
||||||
wc.labels = appendLabels(wc.labels, r.Metric, r.Tags, sw.Config.Labels, sw.Config.HonorLabels)
|
wc.labels = appendLabels(wc.labels, r.Metric, r.Tags, sw.Config.Labels, sw.Config.HonorLabels)
|
||||||
if needRelabel {
|
if needRelabel {
|
||||||
wc.labels = promrelabel.ApplyRelabelConfigs(wc.labels, labelsLen, sw.Config.MetricRelabelConfigs, true)
|
wc.labels = sw.Config.MetricRelabelConfigs.Apply(wc.labels, labelsLen, true)
|
||||||
} else {
|
} else {
|
||||||
wc.labels = promrelabel.FinalizeLabels(wc.labels[:labelsLen], wc.labels[labelsLen:])
|
wc.labels = promrelabel.FinalizeLabels(wc.labels[:labelsLen], wc.labels[labelsLen:])
|
||||||
promrelabel.SortLabels(wc.labels[labelsLen:])
|
promrelabel.SortLabels(wc.labels[labelsLen:])
|
||||||
|
|
|
@ -2,7 +2,6 @@ package promscrape
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -102,7 +101,8 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
|
||||||
sw.PushData = func(wr *prompbmarshal.WriteRequest) {
|
sw.PushData = func(wr *prompbmarshal.WriteRequest) {
|
||||||
pushDataCalls++
|
pushDataCalls++
|
||||||
if len(wr.Timeseries) > len(timeseriesExpected) {
|
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
|
return
|
||||||
}
|
}
|
||||||
tsExpected := timeseriesExpected[:len(wr.Timeseries)]
|
tsExpected := timeseriesExpected[:len(wr.Timeseries)]
|
||||||
|
@ -271,20 +271,14 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
|
||||||
Value: "foo.com",
|
Value: "foo.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MetricRelabelConfigs: []promrelabel.ParsedRelabelConfig{
|
MetricRelabelConfigs: mustParseRelabelConfigs(`
|
||||||
{
|
- action: replace
|
||||||
SourceLabels: []string{"__address__", "job"},
|
source_labels: ["__address__", "job"]
|
||||||
Separator: "/",
|
separator: "/"
|
||||||
TargetLabel: "instance",
|
target_label: "instance"
|
||||||
Regex: defaultRegexForRelabelConfig,
|
- action: labeldrop
|
||||||
Replacement: "$1",
|
regex: c
|
||||||
Action: "replace",
|
`),
|
||||||
},
|
|
||||||
{
|
|
||||||
Action: "labeldrop",
|
|
||||||
Regex: regexp.MustCompile("^c$"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, `
|
}, `
|
||||||
foo{bar="baz",job="xx",instance="foo.com/xx"} 34.44 123
|
foo{bar="baz",job="xx",instance="foo.com/xx"} 34.44 123
|
||||||
bar{a="b",job="xx",instance="foo.com/xx"} -3e4 123
|
bar{a="b",job="xx",instance="foo.com/xx"} -3e4 123
|
||||||
|
@ -311,18 +305,15 @@ func TestScrapeWorkScrapeInternalSuccess(t *testing.T) {
|
||||||
Value: "foo.com",
|
Value: "foo.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MetricRelabelConfigs: []promrelabel.ParsedRelabelConfig{
|
MetricRelabelConfigs: mustParseRelabelConfigs(`
|
||||||
{
|
- action: drop
|
||||||
Action: "drop",
|
separator: ""
|
||||||
SourceLabels: []string{"a", "c"},
|
source_labels: [a, c]
|
||||||
Regex: regexp.MustCompile("^bd$"),
|
regex: "^bd$"
|
||||||
},
|
- action: drop
|
||||||
{
|
source_labels: [__name__]
|
||||||
Action: "drop",
|
regex: "dropme|up"
|
||||||
SourceLabels: []string{"__name__"},
|
`),
|
||||||
Regex: regexp.MustCompile("^(dropme|up)$"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, `
|
}, `
|
||||||
foo{bar="baz",job="xx",instance="foo.com"} 34.44 123
|
foo{bar="baz",job="xx",instance="foo.com"} 34.44 123
|
||||||
up{job="xx",instance="foo.com"} 1 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)
|
fmt.Fprintf(&sb, "%g %d", s.Value, s.Timestamp)
|
||||||
return sb.String()
|
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