OTLP receiver: Use stdlib for splitting metric name in classical mode (#15573)

In non-UTF-8 mode, use strings.FieldsFunc to split string into tokens,
as it was before PR #15258. This makes the code more robust and
readable.

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
Arve Knudsen 2024-12-11 15:12:53 +01:00 committed by GitHub
parent 5cc095e227
commit 9895d882b4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -122,17 +122,22 @@ func BuildCompliantName(metric pmetric.Metric, namespace string, addMetricSuffix
// Build a normalized name for the specified metric.
func normalizeName(metric pmetric.Metric, namespace string, allowUTF8 bool) string {
var translationFunc func(rune) bool
var nameTokens []string
var separators []string
if !allowUTF8 {
nonTokenMetricCharRE := regexp.MustCompile(`[^a-zA-Z0-9:]`)
translationFunc = func(r rune) bool { return nonTokenMetricCharRE.MatchString(string(r)) }
// Split metric name into "tokens" (of supported metric name runes).
// Note that this has the side effect of replacing multiple consecutive underscores with a single underscore.
// This is part of the OTel to Prometheus specification: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.38.0/specification/compatibility/prometheus_and_openmetrics.md#otlp-metric-points-to-prometheus.
nameTokens = strings.FieldsFunc(
metric.Name(),
func(r rune) bool { return nonTokenMetricCharRE.MatchString(string(r)) },
)
} else {
translationFunc = func(r rune) bool { return !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != ':' }
translationFunc := func(r rune) bool { return !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != ':' }
// Split metric name into "tokens" (of supported metric name runes).
nameTokens, separators = fieldsFunc(metric.Name(), translationFunc)
}
// Split metric name into "tokens" (of supported metric name runes).
// Note that this has the side effect of replacing multiple consecutive underscores with a single underscore.
// This is part of the OTel to Prometheus specification: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.38.0/specification/compatibility/prometheus_and_openmetrics.md#otlp-metric-points-to-prometheus.
nameTokens, separators := fieldsFunc(metric.Name(), translationFunc)
// Split unit at the '/' if any
unitTokens := strings.SplitN(metric.Unit(), "/", 2)
@ -201,12 +206,14 @@ func normalizeName(metric pmetric.Metric, namespace string, allowUTF8 bool) stri
nameTokens = append([]string{namespace}, nameTokens...)
}
// Build the string from the tokens + separators.
// If UTF-8 isn't allowed, we'll use underscores as separators.
var normalizedName string
if !allowUTF8 {
separators = []string{}
// Build the string from the tokens, separated with underscores
normalizedName = strings.Join(nameTokens, "_")
} else {
// Build the string from the tokens + separators.
normalizedName = join(nameTokens, separators, "_")
}
normalizedName := join(nameTokens, separators, "_")
// Metric name cannot start with a digit, so prefix it with "_" in this case
if normalizedName != "" && unicode.IsDigit(rune(normalizedName[0])) {