Skip to content

Commit

Permalink
wip: allow utf8
Browse files Browse the repository at this point in the history
Signed-off-by: Arthur Silva Sens <[email protected]>
  • Loading branch information
ArthurSens committed Sep 27, 2024
1 parent 507ec47 commit afc3592
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 6 deletions.
5 changes: 5 additions & 0 deletions exporter/prometheusexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ Given the example, metrics will be available at `https://1.2.3.4:1234/metrics`.

OpenTelemetry metric names and attributes are normalized to be compliant with Prometheus naming rules. [Details on this normalization process are described in the Prometheus translator module](../../pkg/translator/prometheus/).

Prometheus 2.55.0 introduced support for UTF-8 characters behind the feature-flag `utf8-names`. Prometheus 3.0.0 and later accept UTF-8 by default. This means that name and attribute normalization is not required if you're using those versions.
To allow UTF-8 characters to be exposed without normalization, start the collector with the feature gate: `--feature-gates=exporter.prometheus.allow_utf8`.

The scraper must include `scaping=allow-utf-8` in the `Accept` header for UTF-8 characters to be exposed.

## Setting resource attributes as metric labels

By default, resource attributes are added to a special metric called `target_info`. To select and group by metrics by resource attributes, you [need to do join on `target_info`](https://prometheus.io/docs/prometheus/latest/querying/operators/#many-to-one-and-one-to-many-vector-matches). For example, to select metrics with `k8s_namespace_name` attribute equal to `my-namespace`:
Expand Down
24 changes: 18 additions & 6 deletions exporter/prometheusexporter/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,23 @@ func (c *collector) getMetricMetadata(metric pmetric.Metric, attributes pcommon.
keys := make([]string, 0, attributes.Len()+2) // +2 for job and instance labels.
values := make([]string, 0, attributes.Len()+2)

attributes.Range(func(k string, v pcommon.Value) bool {
keys = append(keys, prometheustranslator.NormalizeLabel(k))
values = append(values, v.AsString())
return true
})
var metricName string

if allowUTF8FeatureGate.IsEnabled() {
attributes.Range(func(k string, v pcommon.Value) bool {
keys = append(keys, k)
values = append(values, v.AsString())
return true
})
metricName = metric.Name()
} else {
attributes.Range(func(k string, v pcommon.Value) bool {
keys = append(keys, prometheustranslator.NormalizeLabel(k))
values = append(values, v.AsString())
return true
})
metricName = prometheustranslator.BuildCompliantName(metric, c.namespace, c.addMetricSuffixes)
}

if job, ok := extractJob(resourceAttrs); ok {
keys = append(keys, model.JobLabel)
Expand All @@ -125,7 +137,7 @@ func (c *collector) getMetricMetadata(metric pmetric.Metric, attributes pcommon.
}

return prometheus.NewDesc(
prometheustranslator.BuildCompliantName(metric, c.namespace, c.addMetricSuffixes),
metricName,
metric.Description(),
keys,
c.constLabels,
Expand Down
15 changes: 15 additions & 0 deletions exporter/prometheusexporter/feature_gates.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package prometheusexporter // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusexporter"

import "go.opentelemetry.io/collector/featuregate"

const allowUTF8FeatureGateName = "exporter.prometheus.allowUTF8"

var allowUTF8FeatureGate = featuregate.GlobalRegistry().MustRegister(
allowUTF8FeatureGateName,
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.WithRegisterFromVersion("v0.110.0"),
)
6 changes: 6 additions & 0 deletions exporter/prometheusexporter/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/model"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/exporter"
"go.opentelemetry.io/collector/pdata/pmetric"
Expand Down Expand Up @@ -38,6 +39,11 @@ func newPrometheusExporter(config *Config, set exporter.Settings) (*prometheusEx
collector := newCollector(config, set.Logger)
registry := prometheus.NewRegistry()
_ = registry.Register(collector)

if allowUTF8FeatureGate.IsEnabled() {
model.NameValidationScheme = model.UTF8Validation
}

return &prometheusExporter{
config: *config,
name: set.ID.String(),
Expand Down

0 comments on commit afc3592

Please sign in to comment.