Skip to content

Commit

Permalink
receiver/prometheus: reject datapoints with duplicate label keys (#3408)
Browse files Browse the repository at this point in the history
As of Prometheus 2.16.0 (released on 2020-02-13), datapoints with
duplicate label keys MUST be rejected and the Prometheus RemoteWrite
exporter tests were failing, but that was a red herring as the
real issue was really in the receiver.

Fixes open-telemetry/prometheus-interoperability-spec#44
Fixes #3407
  • Loading branch information
odeke-em authored Jun 10, 2021
1 parent 929538e commit 933504a
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
18 changes: 18 additions & 0 deletions receiver/prometheusreceiver/internal/metricsbuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"errors"
"fmt"
"regexp"
"sort"
"strconv"
"strings"

Expand Down Expand Up @@ -87,6 +88,23 @@ func (b *metricBuilder) matchStartTimeMetric(metricName string) bool {

// AddDataPoint is for feeding prometheus data complexValue in its processing order
func (b *metricBuilder) AddDataPoint(ls labels.Labels, t int64, v float64) error {
// Any datapoint with duplicate labels MUST be rejected per:
// * https://github.com/open-telemetry/wg-prometheus/issues/44
// * https://github.com/open-telemetry/opentelemetry-collector/issues/3407
// as Prometheus rejects such too as of version 2.16.0, released on 2020-02-13.
seen := make(map[string]bool)
dupLabels := make([]string, 0, len(ls))
for _, label := range ls {
if _, ok := seen[label.Name]; ok {
dupLabels = append(dupLabels, label.Name)
}
seen[label.Name] = true
}
if len(dupLabels) != 0 {
sort.Strings(dupLabels)
return fmt.Errorf("invalid sample: non-unique label names: %q", dupLabels)
}

metricName := ls.Get(model.MetricNameLabel)
switch {
case metricName == "":
Expand Down
21 changes: 21 additions & 0 deletions receiver/prometheusreceiver/internal/metricsbuilder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/prometheus/prometheus/pkg/textparse"
"github.com/prometheus/prometheus/scrape"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/wrapperspb"
)

Expand Down Expand Up @@ -1474,3 +1475,23 @@ func Test_heuristicalMetricAndKnownUnits(t *testing.T) {
})
}
}

// Ensure that we reject duplicate label keys. See https://github.com/open-telemetry/wg-prometheus/issues/44.
func TestMetricBuilderDuplicateLabelKeysAreRejected(t *testing.T) {
mc := newMockMetadataCache(testMetadata)
mb := newMetricBuilder(mc, true, "", testLogger)

dupLabels := labels.Labels{
{Name: "__name__", Value: "test"},
{Name: "a", Value: "1"},
{Name: "a", Value: "1"},
{Name: "z", Value: "9"},
{Name: "z", Value: "1"},
{Name: "instance", Value: "0.0.0.0:8855"},
{Name: "job", Value: "test"},
}

err := mb.AddDataPoint(dupLabels, 1917, 1.0)
require.NotNil(t, err)
require.Contains(t, err.Error(), `invalid sample: non-unique label names: ["a" "z"]`)
}

0 comments on commit 933504a

Please sign in to comment.