mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-10-30 00:22:25 -05:00
[chore] bump dependencies (#4406)
- codeberg.org/gruf/go-ffmpreg: v0.6.9 -> v0.6.10
- github.com/ncruces/go-sqlite3: v0.27.1 -> v0.28.0
- github.com/stretchr/testify: v1.10.0 -> v1.11.1
- github.com/tdewolff/minify/v2 v2.23.11 -> v2.24.2
- go.opentelemetry.io/otel{,/*}: v1.37.0 -> v1.38.0
- go.opentelemetry.io/contrib/*: v0.62.0 -> v0.63.0
Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4406
Co-authored-by: kim <grufwub@gmail.com>
Co-committed-by: kim <grufwub@gmail.com>
This commit is contained in:
parent
5a54e7156b
commit
78defcd916
274 changed files with 9213 additions and 2368 deletions
122
vendor/github.com/prometheus/otlptranslator/README.md
generated
vendored
122
vendor/github.com/prometheus/otlptranslator/README.md
generated
vendored
|
|
@ -1,2 +1,120 @@
|
|||
# otlp-prometheus-translator
|
||||
Library providing API to convert OTLP metric and attribute names to respectively Prometheus metric and label names.
|
||||
# OTLP Prometheus Translator
|
||||
|
||||
A Go library for converting [OpenTelemetry Protocol (OTLP)](https://opentelemetry.io/docs/specs/otlp/) metric and attribute names to [Prometheus](https://prometheus.io/)-compliant formats.
|
||||
|
||||
Part of the [Prometheus](https://prometheus.io/) ecosystem, following the [OpenTelemetry to Prometheus compatibility specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/compatibility/prometheus_and_openmetrics.md).
|
||||
|
||||
## Features
|
||||
|
||||
- **Metric Name and Label Translation**: Convert OTLP metric names and attributes to Prometheus-compliant format
|
||||
- **Unit Handling**: Translate OTLP units to Prometheus unit conventions
|
||||
- **Type-Aware Suffixes**: Optionally append `_total`, `_ratio` based on metric type
|
||||
- **Namespace Support**: Add configurable namespace prefixes
|
||||
- **UTF-8 Support**: Choose between Prometheus legacy scheme compliant metric/label names (`[a-zA-Z0-9:_]`) or untranslated metric/label names
|
||||
- **Translation Strategy Configuration**: Select a translation strategy with a standard set of strings.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
go get github.com/prometheus/otlptranslator
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/prometheus/otlptranslator"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create a metric namer using traditional Prometheus name translation, with suffixes added and UTF-8 disallowed.
|
||||
strategy := otlptranslator.UnderscoreEscapingWithSuffixes
|
||||
namer := otlptranslator.NewMetricNamer("myapp", strategy)
|
||||
|
||||
// Translate OTLP metric to Prometheus format
|
||||
metric := otlptranslator.Metric{
|
||||
Name: "http.server.request.duration",
|
||||
Unit: "s",
|
||||
Type: otlptranslator.MetricTypeHistogram,
|
||||
}
|
||||
fmt.Println(namer.Build(metric)) // Output: myapp_http_server_request_duration_seconds
|
||||
|
||||
// Translate label names
|
||||
labelNamer := otlptranslator.LabelNamer{UTF8Allowed: false}
|
||||
fmt.Println(labelNamer.Build("http.method")) // Output: http_method
|
||||
}
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Metric Name Translation
|
||||
|
||||
```go
|
||||
namer := otlptranslator.MetricNamer{WithMetricSuffixes: true, UTF8Allowed: false}
|
||||
|
||||
// Counter gets _total suffix
|
||||
counter := otlptranslator.Metric{
|
||||
Name: "requests.count", Unit: "1", Type: otlptranslator.MetricTypeMonotonicCounter,
|
||||
}
|
||||
fmt.Println(namer.Build(counter)) // requests_count_total
|
||||
|
||||
// Gauge with unit conversion
|
||||
gauge := otlptranslator.Metric{
|
||||
Name: "memory.usage", Unit: "By", Type: otlptranslator.MetricTypeGauge,
|
||||
}
|
||||
fmt.Println(namer.Build(gauge)) // memory_usage_bytes
|
||||
|
||||
// Dimensionless gauge gets _ratio suffix
|
||||
ratio := otlptranslator.Metric{
|
||||
Name: "cpu.utilization", Unit: "1", Type: otlptranslator.MetricTypeGauge,
|
||||
}
|
||||
fmt.Println(namer.Build(ratio)) // cpu_utilization_ratio
|
||||
```
|
||||
|
||||
### Label Translation
|
||||
|
||||
```go
|
||||
labelNamer := otlptranslator.LabelNamer{UTF8Allowed: false}
|
||||
|
||||
labelNamer.Build("http.method") // http_method
|
||||
labelNamer.Build("123invalid") // key_123invalid
|
||||
labelNamer.Build("_private") // key_private
|
||||
labelNamer.Build("__reserved__") // __reserved__ (preserved)
|
||||
labelNamer.Build("label@with$symbols") // label_with_symbols
|
||||
```
|
||||
|
||||
### Unit Translation
|
||||
|
||||
```go
|
||||
unitNamer := otlptranslator.UnitNamer{UTF8Allowed: false}
|
||||
|
||||
unitNamer.Build("s") // seconds
|
||||
unitNamer.Build("By") // bytes
|
||||
unitNamer.Build("requests/s") // requests_per_second
|
||||
unitNamer.Build("1") // "" (dimensionless)
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
|
||||
```go
|
||||
// Prometheus-compliant mode - supports [a-zA-Z0-9:_]
|
||||
compliantNamer := otlptranslator.MetricNamer{UTF8Allowed: false, WithMetricSuffixes: true}
|
||||
|
||||
// Transparent pass-through mode, aka "NoTranslation"
|
||||
utf8Namer := otlptranslator.MetricNamer{UTF8Allowed: true, WithMetricSuffixes: false}
|
||||
utf8Namer = otlptranslator.NewMetricNamer("", otlpTranslator.NoTranslation)
|
||||
|
||||
// With namespace and suffixes
|
||||
productionNamer := otlptranslator.MetricNamer{
|
||||
Namespace: "myservice",
|
||||
WithMetricSuffixes: true,
|
||||
UTF8Allowed: false,
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
|
||||
|
|
|
|||
24
vendor/github.com/prometheus/otlptranslator/doc.go
generated
vendored
Normal file
24
vendor/github.com/prometheus/otlptranslator/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2025 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package otlptranslator provides utilities for converting OpenTelemetry Protocol (OTLP)
|
||||
// metric and attribute names to Prometheus-compliant formats.
|
||||
//
|
||||
// This package is designed to help users translate OpenTelemetry metrics to Prometheus
|
||||
// metrics while following the official OpenTelemetry to Prometheus compatibility specification.
|
||||
//
|
||||
// Main components:
|
||||
// - MetricNamer: Translates OTLP metric names to Prometheus metric names
|
||||
// - LabelNamer: Translates OTLP attribute names to Prometheus label names
|
||||
// - UnitNamer: Translates OTLP units to Prometheus unit conventions
|
||||
package otlptranslator
|
||||
90
vendor/github.com/prometheus/otlptranslator/label_namer.go
generated
vendored
Normal file
90
vendor/github.com/prometheus/otlptranslator/label_namer.go
generated
vendored
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2025 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Provenance-includes-location: https://github.com/prometheus/prometheus/blob/93e991ef7ed19cc997a9360c8016cac3767b8057/storage/remote/otlptranslator/prometheus/normalize_label.go
|
||||
// Provenance-includes-license: Apache-2.0
|
||||
// Provenance-includes-copyright: Copyright The Prometheus Authors
|
||||
// Provenance-includes-location: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/95e8f8fdc2a9dc87230406c9a3cf02be4fd68bea/pkg/translator/prometheus/normalize_label.go
|
||||
// Provenance-includes-license: Apache-2.0
|
||||
// Provenance-includes-copyright: Copyright The OpenTelemetry Authors.
|
||||
|
||||
package otlptranslator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// LabelNamer is a helper struct to build label names.
|
||||
// It translates OpenTelemetry Protocol (OTLP) attribute names to Prometheus-compliant label names.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// namer := LabelNamer{UTF8Allowed: false}
|
||||
// result := namer.Build("http.method") // "http_method"
|
||||
type LabelNamer struct {
|
||||
UTF8Allowed bool
|
||||
}
|
||||
|
||||
// Build normalizes the specified label to follow Prometheus label names standard.
|
||||
//
|
||||
// Translation rules:
|
||||
// - Replaces invalid characters with underscores
|
||||
// - Prefixes labels with invalid start characters (numbers or `_`) with "key"
|
||||
// - Preserves double underscore labels (reserved names)
|
||||
// - If UTF8Allowed is true, returns label as-is
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// namer := LabelNamer{UTF8Allowed: false}
|
||||
// namer.Build("http.method") // "http_method"
|
||||
// namer.Build("123invalid") // "key_123invalid"
|
||||
// namer.Build("__reserved__") // "__reserved__" (preserved)
|
||||
func (ln *LabelNamer) Build(label string) (normalizedName string, err error) {
|
||||
defer func() {
|
||||
if len(normalizedName) == 0 {
|
||||
err = fmt.Errorf("normalization for label name %q resulted in empty name", label)
|
||||
return
|
||||
}
|
||||
|
||||
if ln.UTF8Allowed || normalizedName == label {
|
||||
return
|
||||
}
|
||||
|
||||
// Check that the resulting normalized name contains at least one non-underscore character
|
||||
for _, c := range normalizedName {
|
||||
if c != '_' {
|
||||
return
|
||||
}
|
||||
}
|
||||
err = fmt.Errorf("normalization for label name %q resulted in invalid name %q", label, normalizedName)
|
||||
normalizedName = ""
|
||||
}()
|
||||
|
||||
// Trivial case.
|
||||
if len(label) == 0 || ln.UTF8Allowed {
|
||||
normalizedName = label
|
||||
return
|
||||
}
|
||||
|
||||
normalizedName = sanitizeLabelName(label)
|
||||
|
||||
// If label starts with a number, prepend with "key_".
|
||||
if unicode.IsDigit(rune(normalizedName[0])) {
|
||||
normalizedName = "key_" + normalizedName
|
||||
} else if strings.HasPrefix(normalizedName, "_") && !strings.HasPrefix(normalizedName, "__") {
|
||||
normalizedName = "key" + normalizedName
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
152
vendor/github.com/prometheus/otlptranslator/metric_namer.go
generated
vendored
152
vendor/github.com/prometheus/otlptranslator/metric_namer.go
generated
vendored
|
|
@ -20,6 +20,7 @@
|
|||
package otlptranslator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
|
@ -81,13 +82,48 @@ var perUnitMap = map[string]string{
|
|||
}
|
||||
|
||||
// MetricNamer is a helper struct to build metric names.
|
||||
// It converts OpenTelemetry Protocol (OTLP) metric names to Prometheus-compliant metric names.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// namer := MetricNamer{
|
||||
// WithMetricSuffixes: true,
|
||||
// UTF8Allowed: false,
|
||||
// }
|
||||
//
|
||||
// metric := Metric{
|
||||
// Name: "http.server.duration",
|
||||
// Unit: "s",
|
||||
// Type: MetricTypeHistogram,
|
||||
// }
|
||||
//
|
||||
// result := namer.Build(metric) // "http_server_duration_seconds"
|
||||
type MetricNamer struct {
|
||||
Namespace string
|
||||
WithMetricSuffixes bool
|
||||
UTF8Allowed bool
|
||||
}
|
||||
|
||||
// NewMetricNamer creates a MetricNamer with the specified namespace (can be
|
||||
// blank) and the requested Translation Strategy.
|
||||
func NewMetricNamer(namespace string, strategy TranslationStrategyOption) MetricNamer {
|
||||
return MetricNamer{
|
||||
Namespace: namespace,
|
||||
WithMetricSuffixes: strategy.ShouldAddSuffixes(),
|
||||
UTF8Allowed: !strategy.ShouldEscape(),
|
||||
}
|
||||
}
|
||||
|
||||
// Metric is a helper struct that holds information about a metric.
|
||||
// It represents an OpenTelemetry metric with its name, unit, and type.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// metric := Metric{
|
||||
// Name: "http.server.request.duration",
|
||||
// Unit: "s",
|
||||
// Type: MetricTypeHistogram,
|
||||
// }
|
||||
type Metric struct {
|
||||
Name string
|
||||
Unit string
|
||||
|
|
@ -96,34 +132,70 @@ type Metric struct {
|
|||
|
||||
// Build builds a metric name for the specified metric.
|
||||
//
|
||||
// If UTF8Allowed is true, the metric name is returned as is, only with the addition of type/unit suffixes and namespace preffix if required.
|
||||
// Otherwise the metric name is normalized to be Prometheus-compliant.
|
||||
// See rules at https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels,
|
||||
// https://prometheus.io/docs/practices/naming/#metric-and-label-naming
|
||||
func (mn *MetricNamer) Build(metric Metric) string {
|
||||
// The method applies different transformations based on the MetricNamer configuration:
|
||||
// - If UTF8Allowed is true, doesn't translate names - all characters must be valid UTF-8, however.
|
||||
// - If UTF8Allowed is false, translates metric names to comply with legacy Prometheus name scheme by escaping invalid characters to `_`.
|
||||
// - If WithMetricSuffixes is true, adds appropriate suffixes based on type and unit.
|
||||
//
|
||||
// See rules at https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// namer := MetricNamer{WithMetricSuffixes: true, UTF8Allowed: false}
|
||||
//
|
||||
// // Counter gets _total suffix
|
||||
// counter := Metric{Name: "requests.count", Unit: "1", Type: MetricTypeMonotonicCounter}
|
||||
// result := namer.Build(counter) // "requests_count_total"
|
||||
//
|
||||
// // Gauge with unit suffix
|
||||
// gauge := Metric{Name: "memory.usage", Unit: "By", Type: MetricTypeGauge}
|
||||
// result = namer.Build(gauge) // "memory_usage_bytes"
|
||||
func (mn *MetricNamer) Build(metric Metric) (string, error) {
|
||||
if mn.UTF8Allowed {
|
||||
return mn.buildMetricName(metric.Name, metric.Unit, metric.Type)
|
||||
}
|
||||
return mn.buildCompliantMetricName(metric.Name, metric.Unit, metric.Type)
|
||||
}
|
||||
|
||||
func (mn *MetricNamer) buildCompliantMetricName(name, unit string, metricType MetricType) string {
|
||||
func (mn *MetricNamer) buildCompliantMetricName(name, unit string, metricType MetricType) (normalizedName string, err error) {
|
||||
defer func() {
|
||||
if len(normalizedName) == 0 {
|
||||
err = fmt.Errorf("normalization for metric %q resulted in empty name", name)
|
||||
return
|
||||
}
|
||||
|
||||
if normalizedName == name {
|
||||
return
|
||||
}
|
||||
|
||||
// Check that the resulting normalized name contains at least one non-underscore character
|
||||
for _, c := range normalizedName {
|
||||
if c != '_' {
|
||||
return
|
||||
}
|
||||
}
|
||||
err = fmt.Errorf("normalization for metric %q resulted in invalid name %q", name, normalizedName)
|
||||
normalizedName = ""
|
||||
}()
|
||||
|
||||
// Full normalization following standard Prometheus naming conventions
|
||||
if mn.WithMetricSuffixes {
|
||||
return normalizeName(name, unit, metricType, mn.Namespace)
|
||||
normalizedName = normalizeName(name, unit, metricType, mn.Namespace)
|
||||
return
|
||||
}
|
||||
|
||||
// Simple case (no full normalization, no units, etc.).
|
||||
metricName := strings.Join(strings.FieldsFunc(name, func(r rune) bool {
|
||||
return invalidMetricCharRE.MatchString(string(r))
|
||||
return !isValidCompliantMetricChar(r) && r != '_'
|
||||
}), "_")
|
||||
|
||||
// Namespace?
|
||||
if mn.Namespace != "" {
|
||||
namespace := strings.Join(strings.FieldsFunc(mn.Namespace, func(r rune) bool {
|
||||
return invalidMetricCharRE.MatchString(string(r))
|
||||
return !isValidCompliantMetricChar(r) && r != '_'
|
||||
}), "_")
|
||||
return namespace + "_" + metricName
|
||||
normalizedName = namespace + "_" + metricName
|
||||
return
|
||||
}
|
||||
|
||||
// Metric name starts with a digit? Prefix it with an underscore.
|
||||
|
|
@ -131,14 +203,11 @@ func (mn *MetricNamer) buildCompliantMetricName(name, unit string, metricType Me
|
|||
metricName = "_" + metricName
|
||||
}
|
||||
|
||||
return metricName
|
||||
normalizedName = metricName
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
// Regexp for metric name characters that should be replaced with _.
|
||||
invalidMetricCharRE = regexp.MustCompile(`[^a-zA-Z0-9:_]`)
|
||||
multipleUnderscoresRE = regexp.MustCompile(`__+`)
|
||||
)
|
||||
var multipleUnderscoresRE = regexp.MustCompile(`__+`)
|
||||
|
||||
// isValidCompliantMetricChar checks if a rune is a valid metric name character (a-z, A-Z, 0-9, :).
|
||||
func isValidCompliantMetricChar(r rune) bool {
|
||||
|
|
@ -243,33 +312,54 @@ func removeItem(slice []string, value string) []string {
|
|||
return newSlice
|
||||
}
|
||||
|
||||
func (mn *MetricNamer) buildMetricName(name, unit string, metricType MetricType) string {
|
||||
func (mn *MetricNamer) buildMetricName(inputName, unit string, metricType MetricType) (name string, err error) {
|
||||
name = inputName
|
||||
if mn.Namespace != "" {
|
||||
name = mn.Namespace + "_" + name
|
||||
}
|
||||
|
||||
if mn.WithMetricSuffixes {
|
||||
mainUnitSuffix, perUnitSuffix := buildUnitSuffixes(unit)
|
||||
if mainUnitSuffix != "" {
|
||||
name = name + "_" + mainUnitSuffix
|
||||
}
|
||||
if perUnitSuffix != "" {
|
||||
name = name + "_" + perUnitSuffix
|
||||
}
|
||||
|
||||
// Append _total for Counters
|
||||
if metricType == MetricTypeMonotonicCounter {
|
||||
name += "_total"
|
||||
}
|
||||
|
||||
// Append _ratio for metrics with unit "1"
|
||||
// Some OTel receivers improperly use unit "1" for counters of objects
|
||||
// See https://github.com/open-telemetry/opentelemetry-collector-contrib/issues?q=is%3Aissue+some+metric+units+don%27t+follow+otel+semantic+conventions
|
||||
// Until these issues have been fixed, we're appending `_ratio` for gauges ONLY
|
||||
// Theoretically, counters could be ratios as well, but it's absurd (for mathematical reasons)
|
||||
if unit == "1" && metricType == MetricTypeGauge {
|
||||
name += "_ratio"
|
||||
name = trimSuffixAndDelimiter(name, "ratio")
|
||||
defer func() {
|
||||
name += "_ratio"
|
||||
}()
|
||||
}
|
||||
|
||||
// Append _total for Counters.
|
||||
if metricType == MetricTypeMonotonicCounter {
|
||||
name = trimSuffixAndDelimiter(name, "total")
|
||||
defer func() {
|
||||
name += "_total"
|
||||
}()
|
||||
}
|
||||
|
||||
mainUnitSuffix, perUnitSuffix := buildUnitSuffixes(unit)
|
||||
if perUnitSuffix != "" {
|
||||
name = trimSuffixAndDelimiter(name, perUnitSuffix)
|
||||
defer func() {
|
||||
name = name + "_" + perUnitSuffix
|
||||
}()
|
||||
}
|
||||
// We don't need to trim and re-append the suffix here because this is
|
||||
// the inner-most suffix.
|
||||
if mainUnitSuffix != "" && !strings.HasSuffix(name, mainUnitSuffix) {
|
||||
name = name + "_" + mainUnitSuffix
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// trimSuffixAndDelimiter trims a suffix, plus one extra character which is
|
||||
// assumed to be a delimiter.
|
||||
func trimSuffixAndDelimiter(name, suffix string) string {
|
||||
if strings.HasSuffix(name, suffix) && len(name) > len(suffix)+1 {
|
||||
return name[:len(name)-(len(suffix)+1)]
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
|
|
|||
57
vendor/github.com/prometheus/otlptranslator/normalize_label.go
generated
vendored
57
vendor/github.com/prometheus/otlptranslator/normalize_label.go
generated
vendored
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright 2025 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Provenance-includes-location: https://github.com/prometheus/prometheus/blob/93e991ef7ed19cc997a9360c8016cac3767b8057/storage/remote/otlptranslator/prometheus/normalize_label.go
|
||||
// Provenance-includes-license: Apache-2.0
|
||||
// Provenance-includes-copyright: Copyright The Prometheus Authors
|
||||
// Provenance-includes-location: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/95e8f8fdc2a9dc87230406c9a3cf02be4fd68bea/pkg/translator/prometheus/normalize_label.go
|
||||
// Provenance-includes-license: Apache-2.0
|
||||
// Provenance-includes-copyright: Copyright The OpenTelemetry Authors.
|
||||
|
||||
package otlptranslator
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// LabelNamer is a helper struct to build label names.
|
||||
type LabelNamer struct {
|
||||
UTF8Allowed bool
|
||||
}
|
||||
|
||||
// Build normalizes the specified label to follow Prometheus label names standard.
|
||||
//
|
||||
// See rules at https://prometheus.io/docs/concepts/data_model/#metric-names-and-labels.
|
||||
//
|
||||
// Labels that start with non-letter rune will be prefixed with "key_".
|
||||
// An exception is made for double-underscores which are allowed.
|
||||
//
|
||||
// If UTF8Allowed is true, the label is returned as is. This option is provided just to
|
||||
// keep a consistent interface with the MetricNamer.
|
||||
func (ln *LabelNamer) Build(label string) string {
|
||||
// Trivial case.
|
||||
if len(label) == 0 || ln.UTF8Allowed {
|
||||
return label
|
||||
}
|
||||
|
||||
label = sanitizeLabelName(label)
|
||||
|
||||
// If label starts with a number, prepend with "key_".
|
||||
if unicode.IsDigit(rune(label[0])) {
|
||||
label = "key_" + label
|
||||
} else if strings.HasPrefix(label, "_") && !strings.HasPrefix(label, "__") {
|
||||
label = "key" + label
|
||||
}
|
||||
|
||||
return label
|
||||
}
|
||||
86
vendor/github.com/prometheus/otlptranslator/strategy.go
generated
vendored
Normal file
86
vendor/github.com/prometheus/otlptranslator/strategy.go
generated
vendored
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// Copyright 2025 The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// Provenance-includes-location: https://github.com/prometheus/prometheus/blob/3602785a89162ccc99a940fb9d862219a2d02241/config/config.go
|
||||
// Provenance-includes-license: Apache-2.0
|
||||
// Provenance-includes-copyright: Copyright The Prometheus Authors
|
||||
|
||||
package otlptranslator
|
||||
|
||||
// TranslationStrategyOption is a constant that defines how metric and label
|
||||
// names should be handled during translation. The recommended approach is to
|
||||
// use either UnderscoreEscapingWithSuffixes for full Prometheus-style
|
||||
// compatibility, or NoTranslation for Otel-style names.
|
||||
type TranslationStrategyOption string
|
||||
|
||||
var (
|
||||
// NoUTF8EscapingWithSuffixes will accept metric/label names as they are. Unit
|
||||
// and type suffixes may be added to metric names, according to certain rules.
|
||||
NoUTF8EscapingWithSuffixes TranslationStrategyOption = "NoUTF8EscapingWithSuffixes"
|
||||
// UnderscoreEscapingWithSuffixes is the default option for translating OTLP
|
||||
// to Prometheus. This option will translate metric name characters that are
|
||||
// not alphanumerics/underscores/colons to underscores, and label name
|
||||
// characters that are not alphanumerics/underscores to underscores. Unit and
|
||||
// type suffixes may be appended to metric names, according to certain rules.
|
||||
UnderscoreEscapingWithSuffixes TranslationStrategyOption = "UnderscoreEscapingWithSuffixes"
|
||||
// UnderscoreEscapingWithoutSuffixes translates metric name characters that
|
||||
// are not alphanumerics/underscores/colons to underscores, and label name
|
||||
// characters that are not alphanumerics/underscores to underscores, but
|
||||
// unlike UnderscoreEscapingWithSuffixes it does not append any suffixes to
|
||||
// the names.
|
||||
UnderscoreEscapingWithoutSuffixes TranslationStrategyOption = "UnderscoreEscapingWithoutSuffixes"
|
||||
// NoTranslation (EXPERIMENTAL): disables all translation of incoming metric
|
||||
// and label names. This offers a way for the OTLP users to use native metric
|
||||
// names, reducing confusion.
|
||||
//
|
||||
// WARNING: This setting has significant known risks and limitations (see
|
||||
// https://prometheus.io/docs/practices/naming/ for details): * Impaired UX
|
||||
// when using PromQL in plain YAML (e.g. alerts, rules, dashboard, autoscaling
|
||||
// configuration). * Series collisions which in the best case may result in
|
||||
// OOO errors, in the worst case a silently malformed time series. For
|
||||
// instance, you may end up in situation of ingesting `foo.bar` series with
|
||||
// unit `seconds` and a separate series `foo.bar` with unit `milliseconds`.
|
||||
//
|
||||
// As a result, this setting is experimental and currently, should not be used
|
||||
// in production systems.
|
||||
//
|
||||
// TODO(ArthurSens): Mention `type-and-unit-labels` feature
|
||||
// (https://github.com/prometheus/proposals/pull/39) once released, as
|
||||
// potential mitigation of the above risks.
|
||||
NoTranslation TranslationStrategyOption = "NoTranslation"
|
||||
)
|
||||
|
||||
// ShouldEscape returns true if the translation strategy requires that metric
|
||||
// names be escaped.
|
||||
func (o TranslationStrategyOption) ShouldEscape() bool {
|
||||
switch o {
|
||||
case UnderscoreEscapingWithSuffixes, UnderscoreEscapingWithoutSuffixes:
|
||||
return true
|
||||
case NoTranslation, NoUTF8EscapingWithSuffixes:
|
||||
return false
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// ShouldAddSuffixes returns a bool deciding whether the given translation
|
||||
// strategy should have suffixes added.
|
||||
func (o TranslationStrategyOption) ShouldAddSuffixes() bool {
|
||||
switch o {
|
||||
case UnderscoreEscapingWithSuffixes, NoUTF8EscapingWithSuffixes:
|
||||
return true
|
||||
case UnderscoreEscapingWithoutSuffixes, NoTranslation:
|
||||
return false
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
24
vendor/github.com/prometheus/otlptranslator/unit_namer.go
generated
vendored
24
vendor/github.com/prometheus/otlptranslator/unit_namer.go
generated
vendored
|
|
@ -15,14 +15,34 @@ package otlptranslator
|
|||
import "strings"
|
||||
|
||||
// UnitNamer is a helper for building compliant unit names.
|
||||
// It processes OpenTelemetry Protocol (OTLP) unit strings and converts them
|
||||
// to Prometheus-compliant unit names.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// namer := UnitNamer{UTF8Allowed: false}
|
||||
// result := namer.Build("s") // "seconds"
|
||||
// result = namer.Build("By/s") // "bytes_per_second"
|
||||
type UnitNamer struct {
|
||||
UTF8Allowed bool
|
||||
}
|
||||
|
||||
// Build builds a unit name for the specified unit string.
|
||||
// It processes the unit by splitting it into main and per components,
|
||||
// applying appropriate unit mappings, and cleaning up invalid characters
|
||||
// when the whole UTF-8 character set is not allowed.
|
||||
// applying unit mappings, and cleaning up invalid characters when UTF8Allowed is false.
|
||||
//
|
||||
// Unit mappings include:
|
||||
// - Time: s→seconds, ms→milliseconds, h→hours
|
||||
// - Bytes: By→bytes, KBy→kilobytes, MBy→megabytes
|
||||
// - SI: m→meters, V→volts, W→watts
|
||||
// - Special: 1→"" (empty), %→percent
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// namer := UnitNamer{UTF8Allowed: false}
|
||||
// namer.Build("s") // "seconds"
|
||||
// namer.Build("requests/s") // "requests_per_second"
|
||||
// namer.Build("1") // "" (dimensionless)
|
||||
func (un *UnitNamer) Build(unit string) string {
|
||||
mainUnit, perUnit := buildUnitSuffixes(unit)
|
||||
if !un.UTF8Allowed {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue