mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2025-01-20 07:19:17 +01:00
lib/protoparser/datadog: optimize sanitizeName() function by using result cache for input strings
This is a follow-up for 7c2474dac7
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3105
This commit is contained in:
parent
ef435f8cc4
commit
92b3622253
@ -7,6 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
|
||||||
"github.com/VictoriaMetrics/VictoriaMetrics/lib/cgroup"
|
"github.com/VictoriaMetrics/VictoriaMetrics/lib/cgroup"
|
||||||
@ -155,15 +156,45 @@ var requestPool sync.Pool
|
|||||||
// sanitizeName performs DataDog-compatible santizing for metric names
|
// sanitizeName performs DataDog-compatible santizing for metric names
|
||||||
//
|
//
|
||||||
// See https://docs.datadoghq.com/metrics/custom_metrics/#naming-custom-metrics
|
// See https://docs.datadoghq.com/metrics/custom_metrics/#naming-custom-metrics
|
||||||
func sanitizeName(s string) string {
|
func sanitizeName(name string) string {
|
||||||
s = unsupportedDatadogChars.ReplaceAllString(s, "_")
|
m := sanitizedNames.Load().(*sync.Map)
|
||||||
s = multiUnderscores.ReplaceAllString(s, "_")
|
v, ok := m.Load(name)
|
||||||
s = underscoresWithDots.ReplaceAllString(s, ".")
|
if ok {
|
||||||
return s
|
// Fast path - the sanitized name is found in the cache.
|
||||||
|
sp := v.(*string)
|
||||||
|
return *sp
|
||||||
|
}
|
||||||
|
// Slow path - sanitize name and store it in the cache.
|
||||||
|
sanitizedName := unsupportedDatadogChars.ReplaceAllString(name, "_")
|
||||||
|
sanitizedName = multiUnderscores.ReplaceAllString(sanitizedName, "_")
|
||||||
|
sanitizedName = underscoresWithDots.ReplaceAllString(sanitizedName, ".")
|
||||||
|
// Make a copy of name in order to limit memory usage to the name length,
|
||||||
|
// since the name may point to bigger string.
|
||||||
|
s := string(append([]byte{}, name...))
|
||||||
|
if sanitizedName == name {
|
||||||
|
// point sanitizedName to just allocated s, since it may point to name,
|
||||||
|
// which, in turn, can point to bigger string.
|
||||||
|
sanitizedName = s
|
||||||
|
}
|
||||||
|
sp := &sanitizedName
|
||||||
|
m.Store(s, sp)
|
||||||
|
n := atomic.AddUint64(&sanitizedNamesLen, 1)
|
||||||
|
if n > 100e3 {
|
||||||
|
atomic.StoreUint64(&sanitizedNamesLen, 0)
|
||||||
|
sanitizedNames.Store(&sync.Map{})
|
||||||
|
}
|
||||||
|
return sanitizedName
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
sanitizedNames atomic.Value
|
||||||
|
sanitizedNamesLen uint64
|
||||||
|
|
||||||
unsupportedDatadogChars = regexp.MustCompile(`[^0-9a-zA-Z_\.]+`)
|
unsupportedDatadogChars = regexp.MustCompile(`[^0-9a-zA-Z_\.]+`)
|
||||||
multiUnderscores = regexp.MustCompile(`_+`)
|
multiUnderscores = regexp.MustCompile(`_+`)
|
||||||
underscoresWithDots = regexp.MustCompile(`_?\._?`)
|
underscoresWithDots = regexp.MustCompile(`_?\._?`)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
sanitizedNames.Store(&sync.Map{})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user