diff --git a/config/config.go b/config/config.go index 7099ba325a..9f65a9a1a7 100644 --- a/config/config.go +++ b/config/config.go @@ -31,6 +31,7 @@ import ( "github.com/grafana/regexp" "github.com/prometheus/common/config" "github.com/prometheus/common/model" + "github.com/prometheus/otlptranslator" "github.com/prometheus/sigv4" "gopkg.in/yaml.v2" @@ -104,9 +105,9 @@ func Load(s string, logger *slog.Logger) (*Config, error) { } switch cfg.OTLPConfig.TranslationStrategy { - case UnderscoreEscapingWithSuffixes, UnderscoreEscapingWithoutSuffixes: + case otlptranslator.UnderscoreEscapingWithSuffixes, otlptranslator.UnderscoreEscapingWithoutSuffixes: case "": - case NoTranslation, NoUTF8EscapingWithSuffixes: + case otlptranslator.NoTranslation, otlptranslator.NoUTF8EscapingWithSuffixes: if cfg.GlobalConfig.MetricNameValidationScheme == model.LegacyValidation { return nil, fmt.Errorf("OTLP translation strategy %q is not allowed when UTF8 is disabled", cfg.OTLPConfig.TranslationStrategy) } @@ -257,7 +258,7 @@ var ( // DefaultOTLPConfig is the default OTLP configuration. DefaultOTLPConfig = OTLPConfig{ - TranslationStrategy: UnderscoreEscapingWithSuffixes, + TranslationStrategy: otlptranslator.UnderscoreEscapingWithSuffixes, } ) @@ -1531,79 +1532,14 @@ func getGoGC() int { return DefaultGoGCPercentage } -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 - } -} - // OTLPConfig is the configuration for writing to the OTLP endpoint. type OTLPConfig struct { - PromoteAllResourceAttributes bool `yaml:"promote_all_resource_attributes,omitempty"` - PromoteResourceAttributes []string `yaml:"promote_resource_attributes,omitempty"` - IgnoreResourceAttributes []string `yaml:"ignore_resource_attributes,omitempty"` - TranslationStrategy translationStrategyOption `yaml:"translation_strategy,omitempty"` - KeepIdentifyingResourceAttributes bool `yaml:"keep_identifying_resource_attributes,omitempty"` - ConvertHistogramsToNHCB bool `yaml:"convert_histograms_to_nhcb,omitempty"` + PromoteAllResourceAttributes bool `yaml:"promote_all_resource_attributes,omitempty"` + PromoteResourceAttributes []string `yaml:"promote_resource_attributes,omitempty"` + IgnoreResourceAttributes []string `yaml:"ignore_resource_attributes,omitempty"` + TranslationStrategy otlptranslator.TranslationStrategyOption `yaml:"translation_strategy,omitempty"` + KeepIdentifyingResourceAttributes bool `yaml:"keep_identifying_resource_attributes,omitempty"` + ConvertHistogramsToNHCB bool `yaml:"convert_histograms_to_nhcb,omitempty"` // PromoteScopeMetadata controls whether to promote OTel scope metadata (i.e. name, version, schema URL, and attributes) to metric labels. // As per OTel spec, the aforementioned scope metadata should be identifying, i.e. made into metric labels. PromoteScopeMetadata bool `yaml:"promote_scope_metadata,omitempty"` diff --git a/config/config_test.go b/config/config_test.go index 0673748b98..f95f15b1eb 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -27,6 +27,7 @@ import ( "github.com/prometheus/common/config" "github.com/prometheus/common/model" "github.com/prometheus/common/promslog" + "github.com/prometheus/otlptranslator" "github.com/stretchr/testify/require" "gopkg.in/yaml.v2" @@ -170,7 +171,7 @@ var expectedConf = &Config{ PromoteResourceAttributes: []string{ "k8s.cluster.name", "k8s.job.name", "k8s.namespace.name", }, - TranslationStrategy: UnderscoreEscapingWithSuffixes, + TranslationStrategy: otlptranslator.UnderscoreEscapingWithSuffixes, }, RemoteReadConfigs: []*RemoteReadConfig{ @@ -1828,7 +1829,7 @@ func TestOTLPAllowUTF8(t *testing.T) { verify := func(t *testing.T, conf *Config, err error) { t.Helper() require.NoError(t, err) - require.Equal(t, NoUTF8EscapingWithSuffixes, conf.OTLPConfig.TranslationStrategy) + require.Equal(t, otlptranslator.NoUTF8EscapingWithSuffixes, conf.OTLPConfig.TranslationStrategy) } t.Run("LoadFile", func(t *testing.T) { @@ -1868,7 +1869,7 @@ func TestOTLPAllowUTF8(t *testing.T) { verify := func(t *testing.T, conf *Config, err error) { t.Helper() require.NoError(t, err) - require.Equal(t, NoTranslation, conf.OTLPConfig.TranslationStrategy) + require.Equal(t, otlptranslator.NoTranslation, conf.OTLPConfig.TranslationStrategy) } t.Run("LoadFile", func(t *testing.T) { @@ -1927,7 +1928,7 @@ func TestOTLPAllowUTF8(t *testing.T) { verify := func(t *testing.T, conf *Config, err error) { t.Helper() require.NoError(t, err) - require.Equal(t, UnderscoreEscapingWithSuffixes, conf.OTLPConfig.TranslationStrategy) + require.Equal(t, otlptranslator.UnderscoreEscapingWithSuffixes, conf.OTLPConfig.TranslationStrategy) } t.Run("LoadFile", func(t *testing.T) { diff --git a/go.mod b/go.mod index f038ecf33e..e993819936 100644 --- a/go.mod +++ b/go.mod @@ -206,7 +206,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/otlptranslator v0.0.0-20250620074007-94f535e0c588 + github.com/prometheus/otlptranslator v0.0.0-20250731173911-a9673827589a github.com/prometheus/procfs v0.16.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.2 // indirect diff --git a/go.sum b/go.sum index 4db727944b..14a9b22ff1 100644 --- a/go.sum +++ b/go.sum @@ -460,8 +460,8 @@ github.com/prometheus/common/assets v0.2.0 h1:0P5OrzoHrYBOSM1OigWL3mY8ZvV2N4zIE/ github.com/prometheus/common/assets v0.2.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI= github.com/prometheus/exporter-toolkit v0.14.0 h1:NMlswfibpcZZ+H0sZBiTjrA3/aBFHkNZqE+iCj5EmRg= github.com/prometheus/exporter-toolkit v0.14.0/go.mod h1:Gu5LnVvt7Nr/oqTBUC23WILZepW0nffNo10XdhQcwWA= -github.com/prometheus/otlptranslator v0.0.0-20250620074007-94f535e0c588 h1:QlySqDdSESgWDePeAYskbbcKKdowI26m9aU9zloHyYE= -github.com/prometheus/otlptranslator v0.0.0-20250620074007-94f535e0c588/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= +github.com/prometheus/otlptranslator v0.0.0-20250731173911-a9673827589a h1:r2csuCATbgDz2Nk2PkKo7b6x7ErrF3NMmxwH0fifqN8= +github.com/prometheus/otlptranslator v0.0.0-20250731173911-a9673827589a/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= diff --git a/storage/remote/otlptranslator/prometheusremotewrite/helper.go b/storage/remote/otlptranslator/prometheusremotewrite/helper.go index 2056045f63..691e48de1c 100644 --- a/storage/remote/otlptranslator/prometheusremotewrite/helper.go +++ b/storage/remote/otlptranslator/prometheusremotewrite/helper.go @@ -120,7 +120,7 @@ var seps = []byte{'\xff'} // If settings.PromoteResourceAttributes is not empty, it's a set of resource attributes that should be promoted to labels. func createAttributes(resource pcommon.Resource, attributes pcommon.Map, scope scope, settings Settings, ignoreAttrs []string, logOnOverwrite bool, metadata prompb.MetricMetadata, extras ...string, -) []prompb.Label { +) ([]prompb.Label, error) { resourceAttrs := resource.Attributes() serviceName, haveServiceName := resourceAttrs.Get(conventions.AttributeServiceName) instance, haveInstanceID := resourceAttrs.Get(conventions.AttributeServiceInstanceID) @@ -164,7 +164,10 @@ func createAttributes(resource pcommon.Resource, attributes pcommon.Map, scope s l := make(map[string]string, maxLabelCount) labelNamer := otlptranslator.LabelNamer{UTF8Allowed: settings.AllowUTF8} for _, label := range labels { - finalKey := labelNamer.Build(label.Name) + finalKey, err := labelNamer.Build(label.Name) + if err != nil { + return nil, err + } if existingValue, alreadyExists := l[finalKey]; alreadyExists { l[finalKey] = existingValue + ";" + label.Value } else { @@ -173,17 +176,28 @@ func createAttributes(resource pcommon.Resource, attributes pcommon.Map, scope s } for _, lbl := range promotedAttrs { - normalized := labelNamer.Build(lbl.Name) + normalized, err := labelNamer.Build(lbl.Name) + if err != nil { + return nil, err + } if _, exists := l[normalized]; !exists { l[normalized] = lbl.Value } } if promoteScope { + var rangeErr error scope.attributes.Range(func(k string, v pcommon.Value) bool { - name := labelNamer.Build("otel_scope_" + k) + name, err := labelNamer.Build("otel_scope_" + k) + if err != nil { + rangeErr = err + return false + } l[name] = v.AsString() return true }) + if rangeErr != nil { + return nil, rangeErr + } // Scope Name, Version and Schema URL are added after attributes to ensure they are not overwritten by attributes. l["otel_scope_name"] = scope.name l["otel_scope_version"] = scope.version @@ -233,7 +247,11 @@ func createAttributes(resource pcommon.Resource, attributes pcommon.Map, scope s } // internal labels should be maintained. if len(name) <= 4 || name[:2] != "__" || name[len(name)-2:] != "__" { - name = labelNamer.Build(name) + var err error + name, err = labelNamer.Build(name) + if err != nil { + return nil, err + } } l[name] = extras[i+1] } @@ -243,7 +261,7 @@ func createAttributes(resource pcommon.Resource, attributes pcommon.Map, scope s labels = append(labels, prompb.Label{Name: k, Value: v}) } - return labels + return labels, nil } func aggregationTemporality(metric pmetric.Metric) (pmetric.AggregationTemporality, bool, error) { @@ -278,7 +296,10 @@ func (c *PrometheusConverter) addHistogramDataPoints(ctx context.Context, dataPo pt := dataPoints.At(x) timestamp := convertTimeStamp(pt.Timestamp()) - baseLabels := createAttributes(resource, pt.Attributes(), scope, settings, nil, false, metadata) + baseLabels, err := createAttributes(resource, pt.Attributes(), scope, settings, nil, false, metadata) + if err != nil { + return err + } // If the sum is unset, it indicates the _sum metric point should be // omitted @@ -488,7 +509,10 @@ func (c *PrometheusConverter) addSummaryDataPoints(ctx context.Context, dataPoin pt := dataPoints.At(x) timestamp := convertTimeStamp(pt.Timestamp()) - baseLabels := createAttributes(resource, pt.Attributes(), scope, settings, nil, false, metadata) + baseLabels, err := createAttributes(resource, pt.Attributes(), scope, settings, nil, false, metadata) + if err != nil { + return err + } // treat sum as a sample in an individual TimeSeries sum := &prompb.Sample{ @@ -622,9 +646,9 @@ func (c *PrometheusConverter) addTimeSeriesIfNeeded(lbls []prompb.Label, startTi } // addResourceTargetInfo converts the resource to the target info metric. -func addResourceTargetInfo(resource pcommon.Resource, settings Settings, earliestTimestamp, latestTimestamp time.Time, converter *PrometheusConverter) { +func addResourceTargetInfo(resource pcommon.Resource, settings Settings, earliestTimestamp, latestTimestamp time.Time, converter *PrometheusConverter) error { if settings.DisableTargetInfo { - return + return nil } attributes := resource.Attributes() @@ -642,7 +666,7 @@ func addResourceTargetInfo(resource pcommon.Resource, settings Settings, earlies } if nonIdentifyingAttrsCount == 0 { // If we only have job + instance, then target_info isn't useful, so don't add it. - return + return nil } name := targetMetricName @@ -655,7 +679,10 @@ func addResourceTargetInfo(resource pcommon.Resource, settings Settings, earlies // Do not pass identifying attributes as ignoreAttrs below. identifyingAttrs = nil } - labels := createAttributes(resource, attributes, scope{}, settings, identifyingAttrs, false, prompb.MetricMetadata{}, model.MetricNameLabel, name) + labels, err := createAttributes(resource, attributes, scope{}, settings, identifyingAttrs, false, prompb.MetricMetadata{}, model.MetricNameLabel, name) + if err != nil { + return err + } haveIdentifier := false for _, l := range labels { if l.Name == model.JobLabel || l.Name == model.InstanceLabel { @@ -666,7 +693,7 @@ func addResourceTargetInfo(resource pcommon.Resource, settings Settings, earlies if !haveIdentifier { // We need at least one identifying label to generate target_info. - return + return nil } // Generate target_info samples starting at earliestTimestamp and ending at latestTimestamp, @@ -688,6 +715,7 @@ func addResourceTargetInfo(resource pcommon.Resource, settings Settings, earlies Value: float64(1), Timestamp: latestTimestamp.UnixMilli(), }) + return nil } // convertTimeStamp converts OTLP timestamp in ns to timestamp in ms. diff --git a/storage/remote/otlptranslator/prometheusremotewrite/helper_test.go b/storage/remote/otlptranslator/prometheusremotewrite/helper_test.go index b2e491377f..9ab37e26fd 100644 --- a/storage/remote/otlptranslator/prometheusremotewrite/helper_test.go +++ b/storage/remote/otlptranslator/prometheusremotewrite/helper_test.go @@ -531,7 +531,8 @@ func TestCreateAttributes(t *testing.T) { }), PromoteScopeMetadata: tc.promoteScope, } - lbls := createAttributes(resource, attrs, tc.scope, settings, tc.ignoreAttrs, false, prompb.MetricMetadata{}, model.MetricNameLabel, "test_metric") + lbls, err := createAttributes(resource, attrs, tc.scope, settings, tc.ignoreAttrs, false, prompb.MetricMetadata{}, model.MetricNameLabel, "test_metric") + require.NoError(t, err) require.ElementsMatch(t, lbls, tc.expectedLabels) }) diff --git a/storage/remote/otlptranslator/prometheusremotewrite/histograms.go b/storage/remote/otlptranslator/prometheusremotewrite/histograms.go index 421526926e..f4199fd1c2 100644 --- a/storage/remote/otlptranslator/prometheusremotewrite/histograms.go +++ b/storage/remote/otlptranslator/prometheusremotewrite/histograms.go @@ -52,7 +52,7 @@ func (c *PrometheusConverter) addExponentialHistogramDataPoints(ctx context.Cont return annots, err } - lbls := createAttributes( + lbls, err := createAttributes( resource, pt.Attributes(), scope, @@ -63,7 +63,9 @@ func (c *PrometheusConverter) addExponentialHistogramDataPoints(ctx context.Cont model.MetricNameLabel, metadata.MetricFamilyName, ) - + if err != nil { + return nil, err + } ts, _ := c.getOrCreateTimeSeries(lbls) ts.Histograms = append(ts.Histograms, histogram) @@ -271,7 +273,7 @@ func (c *PrometheusConverter) addCustomBucketsHistogramDataPoints(ctx context.Co return annots, err } - lbls := createAttributes( + lbls, err := createAttributes( resource, pt.Attributes(), scope, @@ -282,6 +284,9 @@ func (c *PrometheusConverter) addCustomBucketsHistogramDataPoints(ctx context.Co model.MetricNameLabel, metadata.MetricFamilyName, ) + if err != nil { + return nil, err + } ts, _ := c.getOrCreateTimeSeries(lbls) ts.Histograms = append(ts.Histograms, histogram) diff --git a/storage/remote/otlptranslator/prometheusremotewrite/histograms_test.go b/storage/remote/otlptranslator/prometheusremotewrite/histograms_test.go index eec7e95240..97f7dc9bca 100644 --- a/storage/remote/otlptranslator/prometheusremotewrite/histograms_test.go +++ b/storage/remote/otlptranslator/prometheusremotewrite/histograms_test.go @@ -847,6 +847,8 @@ func TestPrometheusConverter_addExponentialHistogramDataPoints(t *testing.T) { namer := otlptranslator.MetricNamer{ WithMetricSuffixes: true, } + name, err := namer.Build(TranslatorMetricFromOtelMetric(metric)) + require.NoError(t, err) annots, err := converter.addExponentialHistogramDataPoints( context.Background(), metric.ExponentialHistogram().DataPoints(), @@ -855,7 +857,7 @@ func TestPrometheusConverter_addExponentialHistogramDataPoints(t *testing.T) { ExportCreatedMetric: true, PromoteScopeMetadata: tt.promoteScope, }, - prompb.MetricMetadata{MetricFamilyName: namer.Build(TranslatorMetricFromOtelMetric(metric))}, + prompb.MetricMetadata{MetricFamilyName: name}, pmetric.AggregationTemporalityCumulative, tt.scope, ) @@ -1303,6 +1305,8 @@ func TestPrometheusConverter_addCustomBucketsHistogramDataPoints(t *testing.T) { namer := otlptranslator.MetricNamer{ WithMetricSuffixes: true, } + name, err := namer.Build(TranslatorMetricFromOtelMetric(metric)) + require.NoError(t, err) annots, err := converter.addCustomBucketsHistogramDataPoints( context.Background(), metric.Histogram().DataPoints(), @@ -1312,7 +1316,7 @@ func TestPrometheusConverter_addCustomBucketsHistogramDataPoints(t *testing.T) { ConvertHistogramsToNHCB: true, PromoteScopeMetadata: tt.promoteScope, }, - prompb.MetricMetadata{MetricFamilyName: namer.Build(TranslatorMetricFromOtelMetric(metric))}, + prompb.MetricMetadata{MetricFamilyName: name}, pmetric.AggregationTemporalityCumulative, tt.scope, ) diff --git a/storage/remote/otlptranslator/prometheusremotewrite/metrics_to_prw.go b/storage/remote/otlptranslator/prometheusremotewrite/metrics_to_prw.go index 6488e1e7d1..0eef4e1567 100644 --- a/storage/remote/otlptranslator/prometheusremotewrite/metrics_to_prw.go +++ b/storage/remote/otlptranslator/prometheusremotewrite/metrics_to_prw.go @@ -171,9 +171,14 @@ func (c *PrometheusConverter) FromMetrics(ctx context.Context, md pmetric.Metric continue } + promName, err := namer.Build(TranslatorMetricFromOtelMetric(metric)) + if err != nil { + errs = multierr.Append(errs, err) + continue + } metadata := prompb.MetricMetadata{ Type: otelMetricTypeToPromMetricType(metric), - MetricFamilyName: namer.Build(TranslatorMetricFromOtelMetric(metric)), + MetricFamilyName: promName, Help: metric.Description(), Unit: metric.Unit(), } @@ -273,7 +278,10 @@ func (c *PrometheusConverter) FromMetrics(ctx context.Context, md pmetric.Metric if earliestTimestamp < pcommon.Timestamp(math.MaxUint64) { // We have at least one metric sample for this resource. // Generate a corresponding target_info series. - addResourceTargetInfo(resource, settings, earliestTimestamp.AsTime(), latestTimestamp.AsTime(), c) + err := addResourceTargetInfo(resource, settings, earliestTimestamp.AsTime(), latestTimestamp.AsTime(), c) + if err != nil { + errs = multierr.Append(errs, err) + } } } diff --git a/storage/remote/otlptranslator/prometheusremotewrite/metrics_to_prw_test.go b/storage/remote/otlptranslator/prometheusremotewrite/metrics_to_prw_test.go index 057dc63a7d..d264c81af8 100644 --- a/storage/remote/otlptranslator/prometheusremotewrite/metrics_to_prw_test.go +++ b/storage/remote/otlptranslator/prometheusremotewrite/metrics_to_prw_test.go @@ -310,9 +310,11 @@ func TestFromMetrics(t *testing.T) { } namer := otlptranslator.MetricNamer{} + name, err := namer.Build(TranslatorMetricFromOtelMetric(m)) + require.NoError(t, err) expMetadata = append(expMetadata, prompb.MetricMetadata{ Type: otelMetricTypeToPromMetricType(m), - MetricFamilyName: namer.Build(TranslatorMetricFromOtelMetric(m)), + MetricFamilyName: name, Help: m.Description(), Unit: m.Unit(), }) diff --git a/storage/remote/otlptranslator/prometheusremotewrite/number_data_points.go b/storage/remote/otlptranslator/prometheusremotewrite/number_data_points.go index 68a28c0eca..6992ce20e0 100644 --- a/storage/remote/otlptranslator/prometheusremotewrite/number_data_points.go +++ b/storage/remote/otlptranslator/prometheusremotewrite/number_data_points.go @@ -37,7 +37,7 @@ func (c *PrometheusConverter) addGaugeNumberDataPoints(ctx context.Context, data } pt := dataPoints.At(x) - labels := createAttributes( + labels, err := createAttributes( resource, pt.Attributes(), scope, @@ -48,6 +48,9 @@ func (c *PrometheusConverter) addGaugeNumberDataPoints(ctx context.Context, data model.MetricNameLabel, metadata.MetricFamilyName, ) + if err != nil { + return err + } sample := &prompb.Sample{ // convert ns to ms Timestamp: convertTimeStamp(pt.Timestamp()), @@ -77,7 +80,7 @@ func (c *PrometheusConverter) addSumNumberDataPoints(ctx context.Context, dataPo } pt := dataPoints.At(x) - lbls := createAttributes( + lbls, err := createAttributes( resource, pt.Attributes(), scope, @@ -88,6 +91,9 @@ func (c *PrometheusConverter) addSumNumberDataPoints(ctx context.Context, dataPo model.MetricNameLabel, metadata.MetricFamilyName, ) + if err != nil { + return err + } sample := &prompb.Sample{ // convert ns to ms Timestamp: convertTimeStamp(pt.Timestamp()), diff --git a/storage/remote/write_test.go b/storage/remote/write_test.go index cfe19345f6..9c347ae8e7 100644 --- a/storage/remote/write_test.go +++ b/storage/remote/write_test.go @@ -35,6 +35,7 @@ import ( "github.com/prometheus/client_golang/prometheus" common_config "github.com/prometheus/common/config" "github.com/prometheus/common/model" + "github.com/prometheus/otlptranslator" "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" @@ -392,7 +393,7 @@ func TestOTLPWriteHandler(t *testing.T) { { name: "NoTranslation/NoTypeAndUnitLabels", otlpCfg: config.OTLPConfig{ - TranslationStrategy: config.NoTranslation, + TranslationStrategy: otlptranslator.NoTranslation, }, expectedSamples: []mockSample{ { @@ -418,7 +419,7 @@ func TestOTLPWriteHandler(t *testing.T) { { name: "NoTranslation/WithTypeAndUnitLabels", otlpCfg: config.OTLPConfig{ - TranslationStrategy: config.NoTranslation, + TranslationStrategy: otlptranslator.NoTranslation, }, typeAndUnitLabels: true, expectedSamples: []mockSample{ @@ -447,7 +448,7 @@ func TestOTLPWriteHandler(t *testing.T) { { name: "UnderscoreEscapingWithSuffixes/NoTypeAndUnitLabels", otlpCfg: config.OTLPConfig{ - TranslationStrategy: config.UnderscoreEscapingWithSuffixes, + TranslationStrategy: otlptranslator.UnderscoreEscapingWithSuffixes, }, expectedSamples: []mockSample{ { @@ -473,7 +474,7 @@ func TestOTLPWriteHandler(t *testing.T) { { name: "UnderscoreEscapingWithoutSuffixes", otlpCfg: config.OTLPConfig{ - TranslationStrategy: config.UnderscoreEscapingWithoutSuffixes, + TranslationStrategy: otlptranslator.UnderscoreEscapingWithoutSuffixes, }, expectedSamples: []mockSample{ { @@ -499,7 +500,7 @@ func TestOTLPWriteHandler(t *testing.T) { { name: "UnderscoreEscapingWithSuffixes/WithTypeAndUnitLabels", otlpCfg: config.OTLPConfig{ - TranslationStrategy: config.UnderscoreEscapingWithSuffixes, + TranslationStrategy: otlptranslator.UnderscoreEscapingWithSuffixes, }, typeAndUnitLabels: true, expectedSamples: []mockSample{ @@ -528,7 +529,7 @@ func TestOTLPWriteHandler(t *testing.T) { { name: "NoUTF8EscapingWithSuffixes/NoTypeAndUnitLabels", otlpCfg: config.OTLPConfig{ - TranslationStrategy: config.NoUTF8EscapingWithSuffixes, + TranslationStrategy: otlptranslator.NoUTF8EscapingWithSuffixes, }, expectedSamples: []mockSample{ { @@ -554,7 +555,7 @@ func TestOTLPWriteHandler(t *testing.T) { { name: "NoUTF8EscapingWithSuffixes/WithTypeAndUnitLabels", otlpCfg: config.OTLPConfig{ - TranslationStrategy: config.NoUTF8EscapingWithSuffixes, + TranslationStrategy: otlptranslator.NoUTF8EscapingWithSuffixes, }, typeAndUnitLabels: true, expectedSamples: []mockSample{