summaryrefslogtreecommitdiff
path: root/vendor/github.com/prometheus/otlptranslator
diff options
context:
space:
mode:
authorLibravatar kim <grufwub@gmail.com>2025-07-22 18:00:27 +0200
committerLibravatar kim <gruf@noreply.codeberg.org>2025-07-22 18:00:27 +0200
commitc00cad2cebcb8136a998f6f7ba2c27672f785d10 (patch)
tree863516d8459713cc4b91c83d8aeeef3cac486b39 /vendor/github.com/prometheus/otlptranslator
parent[chore/deps] Upgrade to go-sqlite 0.27.1 (#4334) (diff)
downloadgotosocial-c00cad2cebcb8136a998f6f7ba2c27672f785d10.tar.xz
[chore] bump dependencies (#4339)
- github.com/KimMachineGun/automemlimit v0.7.4 - github.com/miekg/dns v1.1.67 - github.com/minio/minio-go/v7 v7.0.95 - github.com/spf13/pflag v1.0.7 - github.com/tdewolff/minify/v2 v2.23.9 - github.com/uptrace/bun v1.2.15 - github.com/uptrace/bun/dialect/pgdialect v1.2.15 - github.com/uptrace/bun/dialect/sqlitedialect v1.2.15 - github.com/uptrace/bun/extra/bunotel v1.2.15 - golang.org/x/image v0.29.0 - golang.org/x/net v0.42.0 Reviewed-on: https://codeberg.org/superseriousbusiness/gotosocial/pulls/4339 Co-authored-by: kim <grufwub@gmail.com> Co-committed-by: kim <grufwub@gmail.com>
Diffstat (limited to 'vendor/github.com/prometheus/otlptranslator')
-rw-r--r--vendor/github.com/prometheus/otlptranslator/.gitignore25
-rw-r--r--vendor/github.com/prometheus/otlptranslator/.golangci.yml106
-rw-r--r--vendor/github.com/prometheus/otlptranslator/CODE_OF_CONDUCT.md3
-rw-r--r--vendor/github.com/prometheus/otlptranslator/LICENSE201
-rw-r--r--vendor/github.com/prometheus/otlptranslator/MAINTAINERS.md4
-rw-r--r--vendor/github.com/prometheus/otlptranslator/README.md2
-rw-r--r--vendor/github.com/prometheus/otlptranslator/SECURITY.md6
-rw-r--r--vendor/github.com/prometheus/otlptranslator/constants.go38
-rw-r--r--vendor/github.com/prometheus/otlptranslator/metric_namer.go275
-rw-r--r--vendor/github.com/prometheus/otlptranslator/metric_type.go36
-rw-r--r--vendor/github.com/prometheus/otlptranslator/normalize_label.go57
-rw-r--r--vendor/github.com/prometheus/otlptranslator/strconv.go42
-rw-r--r--vendor/github.com/prometheus/otlptranslator/unit_namer.go110
13 files changed, 905 insertions, 0 deletions
diff --git a/vendor/github.com/prometheus/otlptranslator/.gitignore b/vendor/github.com/prometheus/otlptranslator/.gitignore
new file mode 100644
index 000000000..6f72f8926
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/.gitignore
@@ -0,0 +1,25 @@
+# If you prefer the allow list template instead of the deny list, see community template:
+# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
+#
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
+
+# Go workspace file
+go.work
+go.work.sum
+
+# env file
+.env
diff --git a/vendor/github.com/prometheus/otlptranslator/.golangci.yml b/vendor/github.com/prometheus/otlptranslator/.golangci.yml
new file mode 100644
index 000000000..ed5f43f1a
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/.golangci.yml
@@ -0,0 +1,106 @@
+formatters:
+ enable:
+ - gci
+ - gofumpt
+ settings:
+ gci:
+ sections:
+ - standard
+ - default
+ - prefix(github.com/prometheus/otlptranslator)
+ gofumpt:
+ extra-rules: true
+issues:
+ max-issues-per-linter: 0
+ max-same-issues: 0
+linters:
+ # Keep this list sorted alphabetically
+ enable:
+ - depguard
+ - errorlint
+ - exptostd
+ - gocritic
+ - godot
+ - loggercheck
+ - misspell
+ - nilnesserr
+ # TODO: Enable once https://github.com/golangci/golangci-lint/issues/3228 is fixed.
+ # - nolintlint
+ - perfsprint
+ - predeclared
+ - revive
+ - sloglint
+ - testifylint
+ - unconvert
+ - unused
+ - usestdlibvars
+ - whitespace
+ settings:
+ depguard:
+ rules:
+ main:
+ deny:
+ - pkg: sync/atomic
+ desc: Use go.uber.org/atomic instead of sync/atomic
+ - pkg: github.com/stretchr/testify/assert
+ desc: Use github.com/stretchr/testify/require instead of github.com/stretchr/testify/assert
+ - pkg: io/ioutil
+ desc: Use corresponding 'os' or 'io' functions instead.
+ - pkg: regexp
+ desc: Use github.com/grafana/regexp instead of regexp
+ - pkg: github.com/pkg/errors
+ desc: Use 'errors' or 'fmt' instead of github.com/pkg/errors
+ - pkg: golang.org/x/exp/slices
+ desc: Use 'slices' instead.
+ perfsprint:
+ # Optimizes `fmt.Errorf`.
+ errorf: true
+ revive:
+ # By default, revive will enable only the linting rules that are named in the configuration file.
+ # So, it's needed to explicitly enable all required rules here.
+ rules:
+ # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md
+ - name: blank-imports
+ - name: comment-spacings
+ - name: context-as-argument
+ arguments:
+ # Allow functions with test or bench signatures.
+ - allowTypesBefore: '*testing.T,testing.TB'
+ - name: context-keys-type
+ - name: dot-imports
+ - name: early-return
+ arguments:
+ - preserveScope
+ # A lot of false positives: incorrectly identifies channel draining as "empty code block".
+ # See https://github.com/mgechev/revive/issues/386
+ - name: empty-block
+ disabled: true
+ - name: error-naming
+ - name: error-return
+ - name: error-strings
+ - name: errorf
+ - name: exported
+ - name: increment-decrement
+ - name: indent-error-flow
+ arguments:
+ - preserveScope
+ - name: range
+ - name: receiver-naming
+ - name: redefines-builtin-id
+ - name: superfluous-else
+ arguments:
+ - preserveScope
+ - name: time-naming
+ - name: unexported-return
+ - name: unreachable-code
+ - name: unused-parameter
+ - name: var-declaration
+ - name: var-naming
+ testifylint:
+ disable:
+ - float-compare
+ - go-require
+ enable-all: true
+run:
+ timeout: 15m
+version: "2"
diff --git a/vendor/github.com/prometheus/otlptranslator/CODE_OF_CONDUCT.md b/vendor/github.com/prometheus/otlptranslator/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..d325872bd
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/CODE_OF_CONDUCT.md
@@ -0,0 +1,3 @@
+# Prometheus Community Code of Conduct
+
+Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).
diff --git a/vendor/github.com/prometheus/otlptranslator/LICENSE b/vendor/github.com/prometheus/otlptranslator/LICENSE
new file mode 100644
index 000000000..261eeb9e9
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/vendor/github.com/prometheus/otlptranslator/MAINTAINERS.md b/vendor/github.com/prometheus/otlptranslator/MAINTAINERS.md
new file mode 100644
index 000000000..af0fc4df7
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/MAINTAINERS.md
@@ -0,0 +1,4 @@
+* Arthur Silva Sens (arthursens2005@gmail.com / @ArthurSens)
+* Arve Knudsen (arve.knudsen@gmail.com / @aknuds1)
+* Jesús Vázquez (jesus.vazquez@grafana.com / @jesusvazquez)
+* Owen Williams (owen.williams@grafana.com / @ywwg) \ No newline at end of file
diff --git a/vendor/github.com/prometheus/otlptranslator/README.md b/vendor/github.com/prometheus/otlptranslator/README.md
new file mode 100644
index 000000000..3b31a448e
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/README.md
@@ -0,0 +1,2 @@
+# otlp-prometheus-translator
+Library providing API to convert OTLP metric and attribute names to respectively Prometheus metric and label names.
diff --git a/vendor/github.com/prometheus/otlptranslator/SECURITY.md b/vendor/github.com/prometheus/otlptranslator/SECURITY.md
new file mode 100644
index 000000000..fed02d85c
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/SECURITY.md
@@ -0,0 +1,6 @@
+# Reporting a security issue
+
+The Prometheus security policy, including how to report vulnerabilities, can be
+found here:
+
+<https://prometheus.io/docs/operating/security/>
diff --git a/vendor/github.com/prometheus/otlptranslator/constants.go b/vendor/github.com/prometheus/otlptranslator/constants.go
new file mode 100644
index 000000000..0ea3b1c4c
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/constants.go
@@ -0,0 +1,38 @@
+// 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
+
+const (
+ // ExemplarTraceIDKey is the key used to store the trace ID in Prometheus
+ // exemplars:
+ // https://github.com/open-telemetry/opentelemetry-specification/blob/e6eccba97ebaffbbfad6d4358408a2cead0ec2df/specification/compatibility/prometheus_and_openmetrics.md#exemplars
+ ExemplarTraceIDKey = "trace_id"
+ // ExemplarSpanIDKey is the key used to store the Span ID in Prometheus
+ // exemplars:
+ // https://github.com/open-telemetry/opentelemetry-specification/blob/e6eccba97ebaffbbfad6d4358408a2cead0ec2df/specification/compatibility/prometheus_and_openmetrics.md#exemplars
+ ExemplarSpanIDKey = "span_id"
+ // ScopeNameLabelKey is the name of the label key used to identify the name
+ // of the OpenTelemetry scope which produced the metric:
+ // https://github.com/open-telemetry/opentelemetry-specification/blob/e6eccba97ebaffbbfad6d4358408a2cead0ec2df/specification/compatibility/prometheus_and_openmetrics.md#instrumentation-scope
+ ScopeNameLabelKey = "otel_scope_name"
+ // ScopeVersionLabelKey is the name of the label key used to identify the
+ // version of the OpenTelemetry scope which produced the metric:
+ // https://github.com/open-telemetry/opentelemetry-specification/blob/e6eccba97ebaffbbfad6d4358408a2cead0ec2df/specification/compatibility/prometheus_and_openmetrics.md#instrumentation-scope
+ ScopeVersionLabelKey = "otel_scope_version"
+ // TargetInfoMetricName is the name of the metric used to preserve resource
+ // attributes in Prometheus format:
+ // https://github.com/open-telemetry/opentelemetry-specification/blob/e6eccba97ebaffbbfad6d4358408a2cead0ec2df/specification/compatibility/prometheus_and_openmetrics.md#resource-attributes-1
+ // It originates from OpenMetrics:
+ // https://github.com/OpenObservability/OpenMetrics/blob/1386544931307dff279688f332890c31b6c5de36/specification/OpenMetrics.md#supporting-target-metadata-in-both-push-based-and-pull-based-systems
+ TargetInfoMetricName = "target_info"
+)
diff --git a/vendor/github.com/prometheus/otlptranslator/metric_namer.go b/vendor/github.com/prometheus/otlptranslator/metric_namer.go
new file mode 100644
index 000000000..58d68ba98
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/metric_namer.go
@@ -0,0 +1,275 @@
+// 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/metric_name_builder.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_name.go
+// Provenance-includes-license: Apache-2.0
+// Provenance-includes-copyright: Copyright The OpenTelemetry Authors.
+
+package otlptranslator
+
+import (
+ "slices"
+ "strings"
+ "unicode"
+
+ "github.com/grafana/regexp"
+)
+
+// The map to translate OTLP units to Prometheus units
+// OTLP metrics use the c/s notation as specified at https://ucum.org/ucum.html
+// (See also https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/semantic_conventions/README.md#instrument-units)
+// Prometheus best practices for units: https://prometheus.io/docs/practices/naming/#base-units
+// OpenMetrics specification for units: https://github.com/prometheus/OpenMetrics/blob/v1.0.0/specification/OpenMetrics.md#units-and-base-units
+var unitMap = map[string]string{
+ // Time
+ "d": "days",
+ "h": "hours",
+ "min": "minutes",
+ "s": "seconds",
+ "ms": "milliseconds",
+ "us": "microseconds",
+ "ns": "nanoseconds",
+
+ // Bytes
+ "By": "bytes",
+ "KiBy": "kibibytes",
+ "MiBy": "mebibytes",
+ "GiBy": "gibibytes",
+ "TiBy": "tibibytes",
+ "KBy": "kilobytes",
+ "MBy": "megabytes",
+ "GBy": "gigabytes",
+ "TBy": "terabytes",
+
+ // SI
+ "m": "meters",
+ "V": "volts",
+ "A": "amperes",
+ "J": "joules",
+ "W": "watts",
+ "g": "grams",
+
+ // Misc
+ "Cel": "celsius",
+ "Hz": "hertz",
+ "1": "",
+ "%": "percent",
+}
+
+// The map that translates the "per" unit.
+// Example: s => per second (singular).
+var perUnitMap = map[string]string{
+ "s": "second",
+ "m": "minute",
+ "h": "hour",
+ "d": "day",
+ "w": "week",
+ "mo": "month",
+ "y": "year",
+}
+
+// MetricNamer is a helper struct to build metric names.
+type MetricNamer struct {
+ Namespace string
+ WithMetricSuffixes bool
+ UTF8Allowed bool
+}
+
+// Metric is a helper struct that holds information about a metric.
+type Metric struct {
+ Name string
+ Unit string
+ Type MetricType
+}
+
+// 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 {
+ 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 {
+ // Full normalization following standard Prometheus naming conventions
+ if mn.WithMetricSuffixes {
+ return normalizeName(name, unit, metricType, mn.Namespace)
+ }
+
+ // Simple case (no full normalization, no units, etc.).
+ metricName := strings.Join(strings.FieldsFunc(name, func(r rune) bool {
+ return invalidMetricCharRE.MatchString(string(r))
+ }), "_")
+
+ // Namespace?
+ if mn.Namespace != "" {
+ namespace := strings.Join(strings.FieldsFunc(mn.Namespace, func(r rune) bool {
+ return invalidMetricCharRE.MatchString(string(r))
+ }), "_")
+ return namespace + "_" + metricName
+ }
+
+ // Metric name starts with a digit? Prefix it with an underscore.
+ if metricName != "" && unicode.IsDigit(rune(metricName[0])) {
+ metricName = "_" + metricName
+ }
+
+ return metricName
+}
+
+var (
+ // Regexp for metric name characters that should be replaced with _.
+ invalidMetricCharRE = regexp.MustCompile(`[^a-zA-Z0-9:_]`)
+ 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 {
+ return (r >= 'a' && r <= 'z') ||
+ (r >= 'A' && r <= 'Z') ||
+ (r >= '0' && r <= '9') ||
+ r == ':'
+}
+
+// replaceInvalidMetricChar replaces invalid metric name characters with underscore.
+func replaceInvalidMetricChar(r rune) rune {
+ if isValidCompliantMetricChar(r) {
+ return r
+ }
+ return '_'
+}
+
+// Build a normalized name for the specified metric.
+func normalizeName(name, unit string, metricType MetricType, namespace string) string {
+ // 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(
+ name,
+ func(r rune) bool { return !isValidCompliantMetricChar(r) },
+ )
+
+ mainUnitSuffix, perUnitSuffix := buildUnitSuffixes(unit)
+ nameTokens = addUnitTokens(nameTokens, cleanUpUnit(mainUnitSuffix), cleanUpUnit(perUnitSuffix))
+
+ // Append _total for Counters
+ if metricType == MetricTypeMonotonicCounter {
+ nameTokens = append(removeItem(nameTokens, "total"), "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 {
+ nameTokens = append(removeItem(nameTokens, "ratio"), "ratio")
+ }
+
+ // Namespace?
+ if namespace != "" {
+ nameTokens = append([]string{namespace}, nameTokens...)
+ }
+
+ // Build the string from the tokens, separated with underscores
+ normalizedName := strings.Join(nameTokens, "_")
+
+ // Metric name cannot start with a digit, so prefix it with "_" in this case
+ if normalizedName != "" && unicode.IsDigit(rune(normalizedName[0])) {
+ normalizedName = "_" + normalizedName
+ }
+
+ return normalizedName
+}
+
+// addUnitTokens will add the suffixes to the nameTokens if they are not already present.
+// It will also remove trailing underscores from the main suffix to avoid double underscores
+// when joining the tokens.
+//
+// If the 'per' unit ends with underscore, the underscore will be removed. If the per unit is just
+// 'per_', it will be entirely removed.
+func addUnitTokens(nameTokens []string, mainUnitSuffix, perUnitSuffix string) []string {
+ if slices.Contains(nameTokens, mainUnitSuffix) {
+ mainUnitSuffix = ""
+ }
+
+ if perUnitSuffix == "per_" {
+ perUnitSuffix = ""
+ } else {
+ perUnitSuffix = strings.TrimSuffix(perUnitSuffix, "_")
+ if slices.Contains(nameTokens, perUnitSuffix) {
+ perUnitSuffix = ""
+ }
+ }
+
+ if perUnitSuffix != "" {
+ mainUnitSuffix = strings.TrimSuffix(mainUnitSuffix, "_")
+ }
+
+ if mainUnitSuffix != "" {
+ nameTokens = append(nameTokens, mainUnitSuffix)
+ }
+ if perUnitSuffix != "" {
+ nameTokens = append(nameTokens, perUnitSuffix)
+ }
+ return nameTokens
+}
+
+// Remove the specified value from the slice.
+func removeItem(slice []string, value string) []string {
+ newSlice := make([]string, 0, len(slice))
+ for _, sliceEntry := range slice {
+ if sliceEntry != value {
+ newSlice = append(newSlice, sliceEntry)
+ }
+ }
+ return newSlice
+}
+
+func (mn *MetricNamer) buildMetricName(name, unit string, metricType MetricType) string {
+ 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"
+ }
+ }
+ return name
+}
diff --git a/vendor/github.com/prometheus/otlptranslator/metric_type.go b/vendor/github.com/prometheus/otlptranslator/metric_type.go
new file mode 100644
index 000000000..30464cfea
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/metric_type.go
@@ -0,0 +1,36 @@
+// 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
+
+package otlptranslator
+
+// MetricType is a representation of metric types from OpenTelemetry.
+// Different types of Sums were introduced based on their metric temporalities.
+// For more details, see:
+// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#sums
+type MetricType int
+
+const (
+ // MetricTypeUnknown represents an unknown metric type.
+ MetricTypeUnknown = iota
+ // MetricTypeNonMonotonicCounter represents a counter that is not monotonically increasing, also known as delta counter.
+ MetricTypeNonMonotonicCounter
+ // MetricTypeMonotonicCounter represents a counter that is monotonically increasing, also known as cumulative counter.
+ MetricTypeMonotonicCounter
+ // MetricTypeGauge represents a gauge metric.
+ MetricTypeGauge
+ // MetricTypeHistogram represents a histogram metric.
+ MetricTypeHistogram
+ // MetricTypeExponentialHistogram represents an exponential histogram metric.
+ MetricTypeExponentialHistogram
+ // MetricTypeSummary represents a summary metric.
+ MetricTypeSummary
+)
diff --git a/vendor/github.com/prometheus/otlptranslator/normalize_label.go b/vendor/github.com/prometheus/otlptranslator/normalize_label.go
new file mode 100644
index 000000000..aa771f784
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/normalize_label.go
@@ -0,0 +1,57 @@
+// 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
+}
diff --git a/vendor/github.com/prometheus/otlptranslator/strconv.go b/vendor/github.com/prometheus/otlptranslator/strconv.go
new file mode 100644
index 000000000..81d534e8d
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/strconv.go
@@ -0,0 +1,42 @@
+// 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/strconv.go.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_name_test.go
+// Provenance-includes-license: Apache-2.0
+// Provenance-includes-copyright: Copyright The OpenTelemetry Authors.
+
+package otlptranslator
+
+import (
+ "strings"
+)
+
+// sanitizeLabelName replaces any characters not valid according to the
+// classical Prometheus label naming scheme with an underscore.
+// Note: this does not handle all Prometheus label name restrictions (such as
+// not starting with a digit 0-9), and hence should only be used if the label
+// name is prefixed with a known valid string.
+func sanitizeLabelName(name string) string {
+ var b strings.Builder
+ b.Grow(len(name))
+ for _, r := range name {
+ if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') {
+ b.WriteRune(r)
+ } else {
+ b.WriteRune('_')
+ }
+ }
+ return b.String()
+}
diff --git a/vendor/github.com/prometheus/otlptranslator/unit_namer.go b/vendor/github.com/prometheus/otlptranslator/unit_namer.go
new file mode 100644
index 000000000..4bbf93ef9
--- /dev/null
+++ b/vendor/github.com/prometheus/otlptranslator/unit_namer.go
@@ -0,0 +1,110 @@
+// 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
+
+package otlptranslator
+
+import "strings"
+
+// UnitNamer is a helper for building compliant unit names.
+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.
+func (un *UnitNamer) Build(unit string) string {
+ mainUnit, perUnit := buildUnitSuffixes(unit)
+ if !un.UTF8Allowed {
+ mainUnit, perUnit = cleanUpUnit(mainUnit), cleanUpUnit(perUnit)
+ }
+
+ var u string
+ switch {
+ case mainUnit != "" && perUnit != "":
+ u = mainUnit + "_" + perUnit
+ case mainUnit != "":
+ u = mainUnit
+ default:
+ u = perUnit
+ }
+
+ // Clean up leading and trailing underscores
+ if len(u) > 0 && u[0:1] == "_" {
+ u = u[1:]
+ }
+ if len(u) > 0 && u[len(u)-1:] == "_" {
+ u = u[:len(u)-1]
+ }
+
+ return u
+}
+
+// Retrieve the Prometheus "basic" unit corresponding to the specified "basic" unit.
+// Returns the specified unit if not found in unitMap.
+func unitMapGetOrDefault(unit string) string {
+ if promUnit, ok := unitMap[unit]; ok {
+ return promUnit
+ }
+ return unit
+}
+
+// Retrieve the Prometheus "per" unit corresponding to the specified "per" unit.
+// Returns the specified unit if not found in perUnitMap.
+func perUnitMapGetOrDefault(perUnit string) string {
+ if promPerUnit, ok := perUnitMap[perUnit]; ok {
+ return promPerUnit
+ }
+ return perUnit
+}
+
+// buildUnitSuffixes builds the main and per unit suffixes for the specified unit
+// but doesn't do any special character transformation to accommodate Prometheus naming conventions.
+// Removing trailing underscores or appending suffixes is done in the caller.
+func buildUnitSuffixes(unit string) (mainUnitSuffix, perUnitSuffix string) {
+ // Split unit at the '/' if any
+ unitTokens := strings.SplitN(unit, "/", 2)
+
+ if len(unitTokens) > 0 {
+ // Main unit
+ // Update if not blank and doesn't contain '{}'
+ mainUnitOTel := strings.TrimSpace(unitTokens[0])
+ if mainUnitOTel != "" && !strings.ContainsAny(mainUnitOTel, "{}") {
+ mainUnitSuffix = unitMapGetOrDefault(mainUnitOTel)
+ }
+
+ // Per unit
+ // Update if not blank and doesn't contain '{}'
+ if len(unitTokens) > 1 && unitTokens[1] != "" {
+ perUnitOTel := strings.TrimSpace(unitTokens[1])
+ if perUnitOTel != "" && !strings.ContainsAny(perUnitOTel, "{}") {
+ perUnitSuffix = perUnitMapGetOrDefault(perUnitOTel)
+ }
+ if perUnitSuffix != "" {
+ perUnitSuffix = "per_" + perUnitSuffix
+ }
+ }
+ }
+
+ return mainUnitSuffix, perUnitSuffix
+}
+
+// cleanUpUnit cleans up unit so it matches model.LabelNameRE.
+func cleanUpUnit(unit string) string {
+ // Multiple consecutive underscores are replaced 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.
+ return strings.TrimPrefix(multipleUnderscoresRE.ReplaceAllString(
+ strings.Map(replaceInvalidMetricChar, unit),
+ "_",
+ ), "_")
+}