Skip to content

Commit 75fbf41

Browse files
committed
Checking if user label drop configuration did not drop __name__ label
Signed-off-by: Pedro Tanaka <[email protected]>
1 parent 76b68c1 commit 75fbf41

File tree

3 files changed

+40
-1
lines changed

3 files changed

+40
-1
lines changed

pkg/distributor/distributor.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,15 @@ func (d *Distributor) Push(ctx context.Context, req *cortexpb.WriteRequest) (*co
659659
removeLabel(labelName, &ts.Labels)
660660
}
661661

662+
if len(ts.Labels) == 0 || wasNameLabelRemoved(ts.Labels) {
663+
validation.DiscardedExemplars.WithLabelValues(
664+
validation.DroppedByUserConfigurationOverride,
665+
userID,
666+
).Add(float64(len(ts.Samples)))
667+
668+
continue
669+
}
670+
662671
// We rely on sorted labels in different places:
663672
// 1) When computing token for labels, and sharding by all labels. Here different order of labels returns
664673
// different tokens, which is bad.
@@ -784,6 +793,19 @@ func (d *Distributor) Push(ctx context.Context, req *cortexpb.WriteRequest) (*co
784793
return &cortexpb.WriteResponse{}, firstPartialErr
785794
}
786795

796+
func wasNameLabelRemoved(labels []cortexpb.LabelAdapter) bool {
797+
const nameLabel = "__name__"
798+
799+
for i := 0; i < len(labels); i++ {
800+
pair := labels[i]
801+
if pair.Name == nameLabel {
802+
return false
803+
}
804+
}
805+
806+
return true
807+
}
808+
787809
func sortLabelsIfNeeded(labels []cortexpb.LabelAdapter) {
788810
// no need to run sort.Slice, if labels are already sorted, which is most of the time.
789811
// we can avoid extra memory allocations (mostly interface-related) this way.

pkg/distributor/distributor_test.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,17 @@ func TestDistributor_Push_LabelRemoval(t *testing.T) {
11021102
{Name: "__name__", Value: "some_metric"},
11031103
},
11041104
},
1105+
// Edge case: remove label __name__ will drop all user metrics
1106+
{
1107+
removeReplica: true,
1108+
removeLabels: []string{"__name__"},
1109+
inputSeries: labels.Labels{
1110+
{Name: "__name__", Value: "some_metric"},
1111+
{Name: "cluster", Value: "one"},
1112+
{Name: "__replica__", Value: "two"},
1113+
},
1114+
expectedSeries: labels.Labels{},
1115+
},
11051116
// Remove multiple labels and replica.
11061117
{
11071118
removeReplica: true,
@@ -1154,11 +1165,15 @@ func TestDistributor_Push_LabelRemoval(t *testing.T) {
11541165
_, err = ds[0].Push(ctx, req)
11551166
require.NoError(t, err)
11561167

1168+
expectedTimeseriesLen := 0
1169+
if len(tc.expectedSeries) > 0 {
1170+
expectedTimeseriesLen = 1
1171+
}
11571172
// Since each test pushes only 1 series, we do expect the ingester
11581173
// to have received exactly 1 series
11591174
for i := range ingesters {
11601175
timeseries := ingesters[i].series()
1161-
assert.Equal(t, 1, len(timeseries))
1176+
assert.Equal(t, expectedTimeseriesLen, len(timeseries))
11621177
for _, v := range timeseries {
11631178
assert.Equal(t, tc.expectedSeries, cortexpb.FromLabelAdaptersToLabels(v.Labels))
11641179
}

pkg/util/validation/validate.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ const (
5959

6060
// DroppedByRelabelConfiguration Samples can also be discarded because of relabeling configuration
6161
DroppedByRelabelConfiguration = "relabel_configuration"
62+
// DroppedByUserConfigurationOverride Samples discarded due to user configuration removing label __name__
63+
DroppedByUserConfigurationOverride = "user_label_removal_configuration"
6264

6365
// The combined length of the label names and values of an Exemplar's LabelSet MUST NOT exceed 128 UTF-8 characters
6466
// https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#exemplars

0 commit comments

Comments
 (0)