diff --git a/.chloggen/jm-prom-translation-rw2-add-support-for-labels.yaml b/.chloggen/jm-prom-translation-rw2-add-support-for-labels.yaml new file mode 100644 index 000000000000..24e0251534c5 --- /dev/null +++ b/.chloggen/jm-prom-translation-rw2-add-support-for-labels.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: pkg/translator/prometheusremotewrite + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "`FromMetricsV2` now transforms attributes into labels." + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [33661] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/pkg/translator/prometheusremotewrite/metrics_to_prw_v2.go b/pkg/translator/prometheusremotewrite/metrics_to_prw_v2.go index 2beb7385fbe1..5ccd4e166e8a 100644 --- a/pkg/translator/prometheusremotewrite/metrics_to_prw_v2.go +++ b/pkg/translator/prometheusremotewrite/metrics_to_prw_v2.go @@ -8,7 +8,7 @@ import ( "fmt" "strconv" - "github.com/prometheus/prometheus/model/labels" + "github.com/prometheus/prometheus/prompb" writev2 "github.com/prometheus/prometheus/prompb/io/prometheus/write/v2" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" @@ -49,6 +49,7 @@ func (c *prometheusConverterV2) fromMetrics(md pmetric.Metrics, settings Setting resourceMetricsSlice := md.ResourceMetrics() for i := 0; i < resourceMetricsSlice.Len(); i++ { resourceMetrics := resourceMetricsSlice.At(i) + resource := resourceMetrics.Resource() scopeMetricsSlice := resourceMetrics.ScopeMetrics() // keep track of the most recent timestamp in the ResourceMetrics for // use with the "target" info metric @@ -77,7 +78,7 @@ func (c *prometheusConverterV2) fromMetrics(md pmetric.Metrics, settings Setting errs = multierr.Append(errs, fmt.Errorf("empty data points. %s is dropped", metric.Name())) break } - c.addGaugeNumberDataPoints(dataPoints, promName) + c.addGaugeNumberDataPoints(dataPoints, resource, settings, promName) case pmetric.MetricTypeSum: // TODO implement case pmetric.MetricTypeHistogram: @@ -107,16 +108,25 @@ func (c *prometheusConverterV2) timeSeries() []writev2.TimeSeries { return allTS } -func (c *prometheusConverterV2) addSample(sample *writev2.Sample, lbls labels.Labels) *writev2.TimeSeries { +func (c *prometheusConverterV2) addSample(sample *writev2.Sample, lbls []prompb.Label) *writev2.TimeSeries { if sample == nil || len(lbls) == 0 { // This shouldn't happen return nil } - ts := &writev2.TimeSeries{} - ts.LabelsRefs = c.symbolTable.SymbolizeLabels(lbls, ts.LabelsRefs) - ts.Samples = append(ts.Samples, *sample) - c.unique[lbls.Hash()] = ts + buf := make([]uint32, 0, len(lbls)*2) + var off uint32 + for _, l := range lbls { + off = c.symbolTable.Symbolize(l.Name) + buf = append(buf, off) + off = c.symbolTable.Symbolize(l.Value) + buf = append(buf, off) + } + ts := writev2.TimeSeries{ + LabelsRefs: buf, + Samples: []writev2.Sample{*sample}, + } + c.unique[timeSeriesSignature(lbls)] = &ts - return ts + return &ts } diff --git a/pkg/translator/prometheusremotewrite/metrics_to_prw_v2_test.go b/pkg/translator/prometheusremotewrite/metrics_to_prw_v2_test.go index 375738b8bbee..ee56b78428e4 100644 --- a/pkg/translator/prometheusremotewrite/metrics_to_prw_v2_test.go +++ b/pkg/translator/prometheusremotewrite/metrics_to_prw_v2_test.go @@ -27,18 +27,16 @@ func TestFromMetricsV2(t *testing.T) { want := func() map[string]*writev2.TimeSeries { return map[string]*writev2.TimeSeries{ "0": { - LabelsRefs: []uint32{1, 2}, + LabelsRefs: []uint32{1, 2, 3, 4, 5, 6, 7, 8}, Samples: []writev2.Sample{ {Timestamp: convertTimeStamp(pcommon.Timestamp(ts)), Value: 1.23}, }, }, } } + wantedSymbols := []string{"", "series_name_2", "value-2", "series_name_3", "value-3", "__name__", "gauge_1", "series_name_1", "value-1"} tsMap, symbolsTable, err := FromMetricsV2(payload.Metrics(), settings) - wanted := want() require.NoError(t, err) - require.NotNil(t, tsMap) - require.Equal(t, wanted, tsMap) - require.NotNil(t, symbolsTable) - + require.Equal(t, want(), tsMap) + require.ElementsMatch(t, wantedSymbols, symbolsTable.Symbols()) } diff --git a/pkg/translator/prometheusremotewrite/number_data_points_v2.go b/pkg/translator/prometheusremotewrite/number_data_points_v2.go index 3a192efb9589..d2c11447a841 100644 --- a/pkg/translator/prometheusremotewrite/number_data_points_v2.go +++ b/pkg/translator/prometheusremotewrite/number_data_points_v2.go @@ -7,23 +7,26 @@ import ( "math" "github.com/prometheus/common/model" - "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/value" writev2 "github.com/prometheus/prometheus/prompb/io/prometheus/write/v2" + "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" ) -func (c *prometheusConverterV2) addGaugeNumberDataPoints(dataPoints pmetric.NumberDataPointSlice, name string) { +func (c *prometheusConverterV2) addGaugeNumberDataPoints(dataPoints pmetric.NumberDataPointSlice, + resource pcommon.Resource, settings Settings, name string) { for x := 0; x < dataPoints.Len(); x++ { pt := dataPoints.At(x) - // TODO implement support for labels - labels := labels.Labels{ - labels.Label{ - Name: model.MetricNameLabel, - Value: name, - }, - } + labels := createAttributes( + resource, + pt.Attributes(), + settings.ExternalLabels, + nil, + true, + model.MetricNameLabel, + name, + ) sample := &writev2.Sample{ // convert ns to ms diff --git a/pkg/translator/prometheusremotewrite/number_data_points_v2_test.go b/pkg/translator/prometheusremotewrite/number_data_points_v2_test.go index ce78b9c1f391..5b7c2cf377d9 100644 --- a/pkg/translator/prometheusremotewrite/number_data_points_v2_test.go +++ b/pkg/translator/prometheusremotewrite/number_data_points_v2_test.go @@ -108,8 +108,16 @@ func TestPrometheusConverterV2_addGaugeNumberDataPoints(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { metric := tt.metric() + settings := Settings{ + Namespace: "", + ExternalLabels: nil, + DisableTargetInfo: false, + ExportCreatedMetric: false, + AddMetricSuffixes: false, + SendMetadata: false, + } converter := newPrometheusConverterV2() - converter.addGaugeNumberDataPoints(metric.Gauge().DataPoints(), metric.Name()) + converter.addGaugeNumberDataPoints(metric.Gauge().DataPoints(), pcommon.NewResource(), settings, metric.Name()) w := tt.want() diff := cmp.Diff(w, converter.unique, cmpopts.EquateNaNs()) @@ -150,9 +158,18 @@ func TestPrometheusConverterV2_addGaugeNumberDataPointsDuplicate(t *testing.T) { } } + settings := Settings{ + Namespace: "", + ExternalLabels: nil, + DisableTargetInfo: false, + ExportCreatedMetric: false, + AddMetricSuffixes: false, + SendMetadata: false, + } + converter := newPrometheusConverterV2() - converter.addGaugeNumberDataPoints(metric1.Gauge().DataPoints(), metric1.Name()) - converter.addGaugeNumberDataPoints(metric2.Gauge().DataPoints(), metric2.Name()) + converter.addGaugeNumberDataPoints(metric1.Gauge().DataPoints(), pcommon.NewResource(), settings, metric1.Name()) + converter.addGaugeNumberDataPoints(metric2.Gauge().DataPoints(), pcommon.NewResource(), settings, metric2.Name()) assert.Equal(t, want(), converter.unique)