package promrelabel import ( "fmt" "regexp" "testing" "github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal" ) func BenchmarkSanitizeName(b *testing.B) { for _, name := range []string{"", "foo", "foo-bar-baz", "http_requests_total"} { b.Run(name, func(b *testing.B) { benchmarkSanitizeName(b, name) }) } } func benchmarkSanitizeName(b *testing.B, name string) { b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { sanitizedName := SanitizeName(name) GlobalSink += len(sanitizedName) } }) } var GlobalSink int func BenchmarkMatchRegexPrefixDotPlusMatchOptimized(b *testing.B) { const pattern = "^foo.+$" const s = "foobar" prc := newTestRegexRelabelConfig(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if !prc.regex.MatchString(s) { panic(fmt.Errorf("unexpected string mismatch for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexPrefixDotPlusMatchUnoptimized(b *testing.B) { const pattern = "^foo.+$" const s = "foobar" re := regexp.MustCompile(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if !re.MatchString(s) { panic(fmt.Errorf("unexpected string mismatch for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexPrefixDotPlusMismatchOptimized(b *testing.B) { const pattern = "^foo.+$" const s = "xfoobar" prc := newTestRegexRelabelConfig(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if prc.regex.MatchString(s) { panic(fmt.Errorf("unexpected string match for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexPrefixDotPlusMismatchUnoptimized(b *testing.B) { const pattern = "^foo.+$" const s = "xfoobar" re := regexp.MustCompile(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if re.MatchString(s) { panic(fmt.Errorf("unexpected string match for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexPrefixDotStarMatchOptimized(b *testing.B) { const pattern = "^foo.*$" const s = "foobar" prc := newTestRegexRelabelConfig(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if !prc.regex.MatchString(s) { panic(fmt.Errorf("unexpected string mismatch for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexPrefixDotStarMatchUnoptimized(b *testing.B) { const pattern = "^foo.*$" const s = "foobar" re := regexp.MustCompile(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if !re.MatchString(s) { panic(fmt.Errorf("unexpected string mismatch for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexPrefixDotStarMismatchOptimized(b *testing.B) { const pattern = "^foo.*$" const s = "xfoobar" prc := newTestRegexRelabelConfig(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if prc.regex.MatchString(s) { panic(fmt.Errorf("unexpected string match for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexPrefixDotStarMismatchUnoptimized(b *testing.B) { const pattern = "^foo.*$" const s = "xfoobar" re := regexp.MustCompile(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if re.MatchString(s) { panic(fmt.Errorf("unexpected string match for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexSingleValueMatchOptimized(b *testing.B) { const pattern = "^foo$" const s = "foo" prc := newTestRegexRelabelConfig(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if !prc.regex.MatchString(s) { panic(fmt.Errorf("unexpected string mismatch for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexSingleValueMatchUnoptimized(b *testing.B) { const pattern = "^foo$" const s = "foo" re := regexp.MustCompile(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if !re.MatchString(s) { panic(fmt.Errorf("unexpected string mismatch for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexSingleValueMismatchOptimized(b *testing.B) { const pattern = "^foo$" const s = "bar" prc := newTestRegexRelabelConfig(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if prc.regex.MatchString(s) { panic(fmt.Errorf("unexpected string match for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexSingleValueMismatchUnoptimized(b *testing.B) { const pattern = "^foo$" const s = "bar" re := regexp.MustCompile(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if re.MatchString(s) { panic(fmt.Errorf("unexpected string match for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexOrValuesMatchOptimized(b *testing.B) { const pattern = "^(foo|bar|baz|abc)$" const s = "foo" prc := newTestRegexRelabelConfig(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if !prc.regex.MatchString(s) { panic(fmt.Errorf("unexpected string mismatch for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexOrValuesMatchUnoptimized(b *testing.B) { const pattern = "^(foo|bar|baz|abc)$" const s = "foo" re := regexp.MustCompile(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if !re.MatchString(s) { panic(fmt.Errorf("unexpected string mismatch for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexOrValuesMismatchOptimized(b *testing.B) { const pattern = "^(foo|bar|baz|abc)" const s = "qwert" prc := newTestRegexRelabelConfig(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if prc.regex.MatchString(s) { panic(fmt.Errorf("unexpected string match for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkMatchRegexOrValuesMismatchUnoptimized(b *testing.B) { const pattern = "^(foo|bar|baz|abc)$" const s = "qwert" re := regexp.MustCompile(pattern) b.ReportAllocs() b.SetBytes(1) b.RunParallel(func(pb *testing.PB) { for pb.Next() { if re.MatchString(s) { panic(fmt.Errorf("unexpected string match for pattern=%q, s=%q", pattern, s)) } } }) } func BenchmarkApplyRelabelConfigs(b *testing.B) { b.Run("kubernetes", func(b *testing.B) { // See https://github.com/Arnoways/prometheus/blob/d521933053bdf68d252e365da9376706d04addcc/model/relabel/relabel_test.go#L505 pcs := mustParseRelabelConfigs(` - source_labels: - __meta_kubernetes_pod_container_port_name regex: .*-metrics action: keep - source_labels: - __meta_kubernetes_pod_label_name action: drop regex: "" - source_labels: - __meta_kubernetes_pod_phase regex: Succeeded|Failed action: drop - source_labels: - __meta_kubernetes_pod_annotation_prometheus_io_scrape regex: "false" action: drop - source_labels: - __meta_kubernetes_pod_annotation_prometheus_io_scheme target_label: __scheme__ regex: (https?) replacement: $1 action: replace - source_labels: - __meta_kubernetes_pod_annotation_prometheus_io_path target_label: __metrics_path__ regex: (.+) replacement: $1 action: replace - source_labels: - __address__ - __meta_kubernetes_pod_annotation_prometheus_io_port target_label: __address__ regex: (.+?)(\:\d+)?;(\d+) replacement: $1:$3 action: replace - regex: __meta_kubernetes_pod_annotation_prometheus_io_param_(.+) replacement: __param_$1 action: labelmap - regex: __meta_kubernetes_pod_label_prometheus_io_label_(.+) action: labelmap - regex: __meta_kubernetes_pod_annotation_prometheus_io_label_(.+) action: labelmap - source_labels: - __meta_kubernetes_namespace - __meta_kubernetes_pod_label_name separator: / target_label: job replacement: $1 action: replace - source_labels: - __meta_kubernetes_namespace target_label: namespace action: replace - source_labels: - __meta_kubernetes_pod_name target_label: pod action: replace - source_labels: - __meta_kubernetes_pod_container_name target_label: container action: replace - source_labels: - __meta_kubernetes_pod_name - __meta_kubernetes_pod_container_name - __meta_kubernetes_pod_container_port_name separator: ':' target_label: instance action: replace - target_label: cluster replacement: dev-us-central-0 - source_labels: - __meta_kubernetes_namespace regex: hosted-grafana action: drop - source_labels: - __address__ target_label: __tmp_hash modulus: 3 action: hashmod - source_labels: - __tmp_hash regex: ^0$ action: keep - regex: __tmp_hash action: labeldrop `) labelsOrig := labelsFromStrings( "__address__", "10.132.183.40:80", "__meta_kubernetes_namespace", "loki-boltdb-shipper", "__meta_kubernetes_pod_annotation_promtail_loki_boltdb_shipper_hash", "50523b9759094a144adcec2eae0aa4ad", "__meta_kubernetes_pod_annotationpresent_promtail_loki_boltdb_shipper_hash", "true", "__meta_kubernetes_pod_container_init", "false", "__meta_kubernetes_pod_container_name", "promtail", "__meta_kubernetes_pod_container_port_name", "http-metrics", "__meta_kubernetes_pod_container_port_number", "80", "__meta_kubernetes_pod_container_port_protocol", "TCP", "__meta_kubernetes_pod_controller_kind", "DaemonSet", "__meta_kubernetes_pod_controller_name", "promtail-loki-boltdb-shipper", "__meta_kubernetes_pod_host_ip", "10.128.0.178", "__meta_kubernetes_pod_ip", "10.132.183.40", "__meta_kubernetes_pod_label_controller_revision_hash", "555b77cd7d", "__meta_kubernetes_pod_label_name", "promtail-loki-boltdb-shipper", "__meta_kubernetes_pod_label_pod_template_generation", "45", "__meta_kubernetes_pod_labelpresent_controller_revision_hash", "true", "__meta_kubernetes_pod_labelpresent_name", "true", "__meta_kubernetes_pod_labelpresent_pod_template_generation", "true", "__meta_kubernetes_pod_name", "promtail-loki-boltdb-shipper-jgtr7", "__meta_kubernetes_pod_node_name", "gke-dev-us-central-0-main-n2s8-2-14d53341-9hkr", "__meta_kubernetes_pod_phase", "Running", "__meta_kubernetes_pod_ready", "true", "__meta_kubernetes_pod_uid", "4c586419-7f6c-448d-aeec-ca4fa5b05e60", "__metrics_path__", "/metrics", "__scheme__", "http", "__scrape_interval__", "15s", "__scrape_timeout__", "10s", "job", "kubernetes-pods", ) 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) if len(labels) != 0 { panic(fmt.Errorf("BUG: expecting empty labels")) } } }) }) b.Run("replace-label-copy", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: replace source_labels: [id] target_label: __name__ `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != len(labelsOrig) { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labelsOrig)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } 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 != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "id")) } 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("replace-set-label", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: replace target_label: __name__ replacement: foobar `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != len(labelsOrig) { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "foobar" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "foobar")) } if labels[1].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "id")) } 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("replace-add-label", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: replace target_label: aaa replacement: foobar `) labelsOrig := labelsFromStrings( "__name__", "metric", ) 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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 2 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 2, labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } if labels[1].Name != "aaa" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "aaa")) } if labels[1].Value != "foobar" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[1].Value, "foobar")) } } }) }) b.Run("replace-mismatch", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: replace source_labels: ["non-existing-label"] target_label: id regex: "(foobar)-.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != len(labelsOrig) { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } if labels[1].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "id")) } 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("replace-match-regex", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: replace source_labels: [id] target_label: id regex: "(foobar)-.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != len(labelsOrig) { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } if labels[1].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "id")) } if labels[1].Value != "foobar" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[1].Value, "foobar")) } } }) }) b.Run("drop-mismatch", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: drop source_labels: ["non-existing-label"] regex: "(foobar)-.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != len(labelsOrig) { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } if labels[1].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "id")) } 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("drop-match", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: drop source_labels: [id] regex: "yes" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "yes", ) 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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 0 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels)) } } }) }) b.Run("drop-match-regexp", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: drop source_labels: [id] regex: "(foobar)-.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 0 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels)) } } }) }) b.Run("keep-mismatch", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: keep source_labels: ["non-existing-label"] regex: "(foobar)-.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 0 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels)) } } }) }) b.Run("keep-match", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: keep source_labels: [id] regex: "yes" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "yes", ) 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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != len(labelsOrig) { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } if labels[1].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "id")) } if labels[1].Value != "yes" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[1].Value, "yes")) } } }) }) b.Run("keep-match-regexp", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: keep source_labels: [id] regex: "(foobar)-.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != len(labelsOrig) { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } if labels[1].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "id")) } 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("labeldrop-mismatch", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labeldrop regex: "non-existing-label" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != len(labelsOrig) { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } if labels[1].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "id")) } 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("labeldrop-match", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labeldrop regex: id `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 1 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } } }) }) b.Run("labeldrop-match-prefix", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labeldrop regex: "id.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 1 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } } }) }) b.Run("labeldrop-match-regexp", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labeldrop regex: ".*id.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 1 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } } }) }) b.Run("labelkeep-mismatch", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labelkeep regex: "non-existing-label" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 0 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 0, labels)) } } }) }) b.Run("labelkeep-match", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labelkeep regex: id `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 1 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels)) } if labels[0].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "id")) } 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")) } } }) }) b.Run("labelkeep-match-prefix", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labelkeep regex: "id.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 1 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels)) } if labels[0].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "id")) } 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")) } } }) }) b.Run("labelkeep-match-regexp", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labelkeep regex: ".*id.*" `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 1 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 1, labels)) } if labels[0].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "id")) } 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")) } } }) }) b.Run("labelmap-mismatch", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labelmap regex: "a(.*)" `) labelsOrig := labelsFromStrings( "foo", "bar", ) 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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) 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 := labelsFromStrings( "aabc", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 2 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 3, labels)) } if labels[0].Name != "aabc" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "aabc")) } 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 != "abc" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "abc")) } 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("labelmap-match-regexp", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: labelmap regex: "(.*)bc" `) labelsOrig := labelsFromStrings( "aabc", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != 2 { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), 3, labels)) } if labels[0].Name != "aa" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "aa")) } if labels[0].Value != "foobar-random-string-here" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "foobar-random-string-here")) } if labels[1].Name != "aabc" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "aabc")) } if labels[1].Value != "foobar-random-string-here" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[1].Value, "foobar-random-string-here")) } } }) }) b.Run("hashmod", func(b *testing.B) { pcs := mustParseRelabelConfigs(` - action: hashmod source_labels: [id] target_label: id modulus: 23 `) labelsOrig := labelsFromStrings( "__name__", "metric", "id", "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) labels = FinalizeLabels(labels[:0], labels) SortLabels(labels) if len(labels) != len(labelsOrig) { panic(fmt.Errorf("unexpected number of labels; got %d; want %d; labels:\n%#v", len(labels), len(labelsOrig), labels)) } if labels[0].Name != "__name__" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[0].Name, "__name__")) } if labels[0].Value != "metric" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[0].Value, "metric")) } if labels[1].Name != "id" { panic(fmt.Errorf("unexpected label name; got %q; want %q", labels[1].Name, "id")) } if labels[1].Value != "11" { panic(fmt.Errorf("unexpected label value; got %q; want %q", labels[1].Value, "11")) } } }) }) } func mustParseRelabelConfigs(config string) *ParsedConfigs { pcs, err := ParseRelabelConfigsData([]byte(config), false) if err != nil { panic(fmt.Errorf("unexpected error: %w", err)) } return pcs } func labelsFromStrings(ss ...string) []prompbmarshal.Label { labelsLen := len(ss) / 2 labels := make([]prompbmarshal.Label, 0, labelsLen) for i := 0; i < len(ss); i += 2 { labels = append(labels, prompbmarshal.Label{ Name: ss[i], Value: ss[i+1], }) } return labels }