diff --git a/pkg/bloomgateway/querier.go b/pkg/bloomgateway/querier.go index a6209f9ccf34a..6fc6e993be645 100644 --- a/pkg/bloomgateway/querier.go +++ b/pkg/bloomgateway/querier.go @@ -22,6 +22,7 @@ type querierMetrics struct { chunksFiltered prometheus.Counter seriesTotal prometheus.Counter seriesFiltered prometheus.Counter + seriesSkipped prometheus.Counter } func newQuerierMetrics(registerer prometheus.Registerer, namespace, subsystem string) *querierMetrics { @@ -50,6 +51,12 @@ func newQuerierMetrics(registerer prometheus.Registerer, namespace, subsystem st Name: "series_filtered_total", Help: "Total amount of series that have been filtered out. Does not count series in failed requests.", }), + seriesSkipped: promauto.With(registerer).NewCounter(prometheus.CounterOpts{ + Namespace: namespace, + Subsystem: subsystem, + Name: "series_skipped_total", + Help: "Total amount of series that have been skipped and returned unfiltered, because no block matched the series.", + }), } } @@ -114,6 +121,7 @@ func (bq *BloomQuerier) FilterChunkRefs(ctx context.Context, tenant string, from "series", len(s.series), "chunks", chunks, "blocks", len(blocks), + "skipped", len(skipped), ) refs, err := bq.c.FilterChunks(ctx, tenant, s.interval, blocks, queryPlan) @@ -123,6 +131,7 @@ func (bq *BloomQuerier) FilterChunkRefs(ctx context.Context, tenant string, from // add chunk refs from series that were not mapped to any blocks refs = append(refs, skipped...) + bq.metrics.seriesSkipped.Add(float64(len(skipped))) for i := range refs { seriesSeen[refs[i].Fingerprint] = struct{}{} diff --git a/pkg/bloomgateway/resolver.go b/pkg/bloomgateway/resolver.go index c10ebc33dff3e..c5b24115a211f 100644 --- a/pkg/bloomgateway/resolver.go +++ b/pkg/bloomgateway/resolver.go @@ -110,14 +110,14 @@ func unassignedSeries(mapped []blockWithSeries, series []*logproto.GroupedChunkR }) maxIdx := sort.Search(len(skipped), func(i int) bool { - return skipped[i].Fingerprint >= maxFp.Fingerprint + return skipped[i].Fingerprint > maxFp.Fingerprint }) if minIdx == len(skipped) || maxIdx == 0 || minIdx == maxIdx { continue } - skipped = append(skipped[0:minIdx], skipped[maxIdx+1:]...) + skipped = append(skipped[0:minIdx], skipped[maxIdx:]...) } return skipped diff --git a/pkg/bloomgateway/resolver_test.go b/pkg/bloomgateway/resolver_test.go index 7214537d6885c..e6369cbeff9ea 100644 --- a/pkg/bloomgateway/resolver_test.go +++ b/pkg/bloomgateway/resolver_test.go @@ -242,12 +242,34 @@ func TestBlockResolver_UnassignedSeries(t *testing.T) { {Fingerprint: 0xe0}, }, }, + { + desc: "block overlapping single remaining series", + mapped: []blockWithSeries{ + { + series: []*logproto.GroupedChunkRefs{ + {Fingerprint: 0x00}, + {Fingerprint: 0x20}, + {Fingerprint: 0x40}, + {Fingerprint: 0x60}, + {Fingerprint: 0x80}, + {Fingerprint: 0xa0}, + {Fingerprint: 0xc0}, + }, + }, + { + series: []*logproto.GroupedChunkRefs{ + {Fingerprint: 0xe0}, + }, + }, + }, + expected: []*logproto.GroupedChunkRefs{}, + }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { result := unassignedSeries(tc.mapped, series) - require.Equal(t, result, tc.expected) + require.Equal(t, tc.expected, result) }) } }