-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Arthur Silva Sens <[email protected]>
- Loading branch information
1 parent
507ec47
commit c6164f8
Showing
11 changed files
with
243 additions
and
108 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package prometheus // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheus" | ||
|
||
import ( | ||
"github.com/prometheus/common/model" | ||
"go.opentelemetry.io/collector/featuregate" | ||
) | ||
|
||
var ( | ||
dropSanitizationGate = featuregate.GlobalRegistry().MustRegister( | ||
"pkg.translator.prometheus.PermissiveLabelSanitization", | ||
featuregate.StageAlpha, | ||
featuregate.WithRegisterDescription("Controls whether to change labels starting with '_' to 'key_'."), | ||
featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/8950"), | ||
) | ||
|
||
normalizeNameGate = featuregate.GlobalRegistry().MustRegister( | ||
"pkg.translator.prometheus.NormalizeName", | ||
featuregate.StageBeta, | ||
featuregate.WithRegisterDescription("Controls whether metrics names are automatically normalized to follow Prometheus naming convention"), | ||
featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/8950"), | ||
) | ||
|
||
allowUTF8FeatureGate = featuregate.GlobalRegistry().MustRegister( | ||
"pkg.translator.prometheus.allowUTF8", | ||
featuregate.StageAlpha, | ||
featuregate.WithRegisterDescription("When enabled, metric names and labels will not be normalized to the traditional Prometheus naming rules, fundamentally allowing UTF-8 characters."), | ||
featuregate.WithRegisterReferenceURL("https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/35459"), | ||
featuregate.WithRegisterFromVersion("v0.110.0"), | ||
) | ||
) | ||
|
||
func init() { | ||
if allowUTF8FeatureGate.IsEnabled() { | ||
model.NameValidationScheme = model.UTF8Validation | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
// Copyright The OpenTelemetry Authors | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package prometheus // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheus" | ||
|
||
import ( | ||
"strings" | ||
"unicode" | ||
|
||
"go.opentelemetry.io/collector/pdata/pmetric" | ||
) | ||
|
||
type Translator interface { | ||
TranslateAttribute(string) string | ||
TranslateMetric(metric pmetric.Metric, namespace string, addMetricSuffixes bool) string | ||
} | ||
|
||
type UTF8AllowedTranslator struct{} | ||
|
||
func (UTF8AllowedTranslator) TranslateAttribute(attribute string) string { | ||
return addKeyPrefixIfNeeded(attribute) | ||
} | ||
|
||
func (UTF8AllowedTranslator) TranslateMetric(metric pmetric.Metric, namespace string, addMetricSuffixes bool) string { | ||
tokens := make([]string, 0) | ||
if namespace != "" { | ||
tokens = append(tokens, namespace) | ||
} | ||
tokens = append(tokens, metric.Name()) | ||
|
||
if addMetricSuffixes && normalizeNameGate.IsEnabled() { | ||
// Split unit at the '/' if any | ||
unitTokens := strings.SplitN(metric.Unit(), "/", 2) | ||
|
||
if len(unitTokens) > 0 { | ||
mainUnitOtel := strings.TrimSpace(unitTokens[0]) | ||
if mainUnitOtel != "" && !strings.ContainsAny(mainUnitOtel, "{}") { | ||
tokens = append(tokens, unitMapGetOrDefault(mainUnitOtel)) | ||
} | ||
|
||
// Per unit | ||
// Append if not blank and doesn't contain '{}' | ||
if len(unitTokens) > 1 && unitTokens[1] != "" { | ||
perUnitOtel := strings.TrimSpace(unitTokens[1]) | ||
if perUnitOtel != "" && !strings.ContainsAny(perUnitOtel, "{}") { | ||
tokens = append(tokens, perUnitMapGetOrDefault(perUnitOtel)) | ||
} | ||
} | ||
|
||
} | ||
} | ||
|
||
metricName := strings.Join(tokens, ".") | ||
|
||
// Append _total for Counters | ||
if addMetricSuffixes && normalizeNameGate.IsEnabled() && metric.Type() == pmetric.MetricTypeSum && metric.Sum().IsMonotonic() { | ||
metricName += "_total" | ||
} | ||
return metricName | ||
} | ||
|
||
type ClassicTranslator struct{} | ||
|
||
func (ClassicTranslator) TranslateAttribute(attribute string) string { | ||
// Trivial case | ||
if len(attribute) == 0 { | ||
return attribute | ||
} | ||
|
||
// Replace all non-alphanumeric runes with underscores | ||
attribute = strings.Map(sanitizeRune, attribute) | ||
attribute = addKeyPrefixIfNeeded(attribute) | ||
|
||
return attribute | ||
} | ||
|
||
// Return '_' for anything non-alphanumeric | ||
func sanitizeRune(r rune) rune { | ||
if unicode.IsLetter(r) || unicode.IsDigit(r) { | ||
return r | ||
} | ||
return '_' | ||
} | ||
|
||
func addKeyPrefixIfNeeded(attribute string) string { | ||
// If label starts with a number, prepend with "key_" | ||
if unicode.IsDigit(rune(attribute[0])) { | ||
attribute = "key_" + attribute | ||
} else if strings.HasPrefix(attribute, "_") && !strings.HasPrefix(attribute, "__") && !dropSanitizationGate.IsEnabled() { | ||
attribute = "key" + attribute | ||
} | ||
return attribute | ||
} | ||
|
||
func (ClassicTranslator) TranslateMetric(metric pmetric.Metric, namespace string, addMetricSuffixes bool) string { | ||
return BuildCompliantName(metric, namespace, addMetricSuffixes) | ||
} | ||
|
||
func NewTranslator() Translator { | ||
if allowUTF8FeatureGate.IsEnabled() { | ||
return UTF8AllowedTranslator{} | ||
} | ||
return ClassicTranslator{} | ||
} |
Oops, something went wrong.