Skip to content

Commit

Permalink
feat: 优化指标名校验性能 --story=119194100 (#486)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiandongx authored Aug 14, 2024
1 parent 6004c92 commit 485d1cb
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 6 deletions.
2 changes: 1 addition & 1 deletion pkg/collector/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.65.x
0.66.x
14 changes: 14 additions & 0 deletions pkg/collector/internal/utils/normalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,17 @@ import (
func NormalizeName(s string) string {
return strings.Join(strings.FieldsFunc(s, func(r rune) bool { return !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != '_' && r != ':' }), "_")
}

// IsNameNormalized 判断是否为合法指标名称
// 此方式会比 regexp 方式要更快 参见 benchmark
func IsNameNormalized(s string) bool {
if len(s) == 0 {
return false
}
for i, b := range s {
if !((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || (b >= '0' && b <= '9' && i > 0)) {
return false
}
}
return true
}
45 changes: 45 additions & 0 deletions pkg/collector/internal/utils/normalize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package utils

import (
"regexp"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -56,3 +57,47 @@ func TestNormalize(t *testing.T) {
assert.Equal(t, c.Output, NormalizeName(c.Input))
}
}

func benchmarkIsNormalized(b *testing.B, f func(string) bool) {
type Case struct {
Input string
Validated bool
}

cases := []Case{
{Input: "foo.bar", Validated: false},
{Input: "foo.bar.zzz", Validated: false},
{Input: "foo.bar..", Validated: false},
{Input: "TestApp_HelloGo_HelloGoObjAdapter_connectRate", Validated: true},
{Input: "TestApp_HelloGo_HelloGoObjAdapter.connectRate", Validated: false},
{Input: "TestApp.HelloGo.exception_single_log_more_than_3M", Validated: false},
{Input: "TestApp_HelloGo_exception_single_log_more_than_3M", Validated: true},
{Input: "TestApp.HelloGo.asyncqueue0", Validated: false},
{Input: "Exception-Log", Validated: false},
{Input: "┓(-´∀`-)┏", Validated: false},
}

b.ReportAllocs()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
for _, c := range cases {
ok := f(c.Input)
if c.Validated != ok {
b.Errorf("input=(%v), want '%v' but go '%v'", c.Input, c.Validated, ok)
}
}
}
})
}

func BenchmarkIsNormalizedFast(b *testing.B) {
benchmarkIsNormalized(b, IsNameNormalized)
}

func BenchmarkIsNormalizedRegex(b *testing.B) {
namePattern := regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
f := func(s string) bool {
return namePattern.MatchString(s)
}
benchmarkIsNormalized(b, f)
}
7 changes: 2 additions & 5 deletions pkg/collector/processor/proxyvalidator/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
package proxyvalidator

import (
"regexp"
"time"

"github.com/pkg/errors"
"github.com/spf13/cast"

"github.com/TencentBlueKing/bkmonitor-datalink/pkg/collector/define"
"github.com/TencentBlueKing/bkmonitor-datalink/pkg/collector/internal/utils"
)

const (
Expand All @@ -28,8 +28,6 @@ type Validator interface {
Validate(*define.ProxyData) error
}

var namePattern = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")

type noneValidator struct{}

func (noneValidator) Validate(*define.ProxyData) error {
Expand All @@ -39,10 +37,9 @@ func (noneValidator) Validate(*define.ProxyData) error {
type nameValidator struct{}

func (nv *nameValidator) Validate(s string) error {
if !namePattern.MatchString(s) {
if !utils.IsNameNormalized(s) {
return errors.Errorf("name '%s' required match regex [^[a-zA-Z_][a-zA-Z0-9_]*$]", s)
}

return nil
}

Expand Down

0 comments on commit 485d1cb

Please sign in to comment.