Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Push down label_name filter on Series API #2163

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
368 changes: 189 additions & 179 deletions api/gen/proto/go/ingester/v1/ingester.pb.go

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions api/gen/proto/go/ingester/v1/ingester_vtproto.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/ingester/v1/ingester.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ message ProfileTypesResponse {

message SeriesRequest {
repeated string matchers = 1;
repeated string label_names = 2;
}

message SeriesResponse {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,11 @@ limits:
# Maximum size of a profile in bytes. This is based off the uncompressed size.
# 0 to disable.
# CLI flag: -validation.max-profile-size-bytes
[max_profile_size_bytes: <int> | default = 2097152]
[max_profile_size_bytes: <int> | default = 4194304]

# Maximum number of samples in a profile. 0 to disable.
# CLI flag: -validation.max-profile-stacktrace-samples
[max_profile_stacktrace_samples: <int> | default = 2000]
[max_profile_stacktrace_samples: <int> | default = 4000]

# Maximum number of labels in a profile sample. 0 to disable.
# CLI flag: -validation.max-profile-stacktrace-sample-labels
Expand Down
2 changes: 2 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ github.com/go-kit/kit v0.12.0 h1:e4o3o3IsBfAKQh5Qbbiqyfu97Ku7jrO/JbohvztANh4=
github.com/go-kit/kit v0.12.0/go.mod h1:lHd+EkCZPIwYItmGDDRdhinkzX2A1sj+M9biaEaizzs=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc=
github.com/go-openapi/runtime v0.25.0/go.mod h1:Ux6fikcHXyyob6LNWxtE96hWwjBPYF0DXgVFuMTneOs=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
Expand Down Expand Up @@ -739,6 +740,7 @@ github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJV
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/slok/go-http-metrics v0.9.0 h1:o7A7j2DHs7Bnz8aGMotQLele28vf/Cl+O9cwJ6HyGk4=
github.com/slok/go-http-metrics v0.9.0/go.mod h1:VCio4Xl8m11JM/0Sl9265RdKyiMypzMo3w1M8xcZGtk=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
Expand Down
14 changes: 14 additions & 0 deletions pkg/phlaredb/head.go
Original file line number Diff line number Diff line change
Expand Up @@ -877,9 +877,22 @@ func (h *Head) Series(ctx context.Context, req *connect.Request[ingestv1.SeriesR
if err != nil {
return nil, err
}

// build up map of label names
labelNameMap := make(map[string]struct{}, len(req.Msg.LabelNames))
for _, labelName := range req.Msg.LabelNames {
labelNameMap[labelName] = struct{}{}
}

response := &ingestv1.SeriesResponse{}
uniqu := map[model.Fingerprint]struct{}{}
if err := h.forMatchingSelectors(selectors, func(lbs phlaremodel.Labels, fp model.Fingerprint) error {
if len(req.Msg.LabelNames) > 0 {
lbs = lbs.WithLabels(req.Msg.LabelNames...)
fp = model.Fingerprint(lbs.Hash())

}

if _, ok := uniqu[fp]; ok {
return nil
}
Expand All @@ -889,6 +902,7 @@ func (h *Head) Series(ctx context.Context, req *connect.Request[ingestv1.SeriesR
}); err != nil {
return nil, err
}

sort.Slice(response.LabelsSet, func(i, j int) bool {
return phlaremodel.CompareLabelPairs(response.LabelsSet[i].Labels, response.LabelsSet[j].Labels) < 0
})
Expand Down
18 changes: 15 additions & 3 deletions pkg/phlaredb/head_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,18 +307,30 @@ func TestHeadSeries(t *testing.T) {
require.NoError(t, head.Ingest(context.Background(), newProfileFoo(), uuid.New(), fooLabels...))
require.NoError(t, head.Ingest(context.Background(), newProfileBar(), uuid.New(), barLabels...))

expected := phlaremodel.NewLabelsBuilder(nil).
lblBuilder := phlaremodel.NewLabelsBuilder(nil).
Set("namespace", "phlare").
Set("job", "foo").
Set("__period_type__", "type").
Set("__period_unit__", "unit").
Set("__type__", "type").
Set("__unit__", "unit").
Set("__profile_type__", ":type:unit:type:unit").
Labels()
Set("__profile_type__", ":type:unit:type:unit")
expected := lblBuilder.Labels()
res, err := head.Series(context.Background(), connect.NewRequest(&ingestv1.SeriesRequest{Matchers: []string{`{job="foo"}`}}))
require.NoError(t, err)
require.Equal(t, []*typesv1.Labels{{Labels: expected}}, res.Msg.LabelsSet)

// Test we can filter labelNames
res, err = head.Series(context.Background(), connect.NewRequest(&ingestv1.SeriesRequest{LabelNames: []string{"job", "not-existing"}}))
require.NoError(t, err)
lblBuilder.Reset(nil)
jobFoo := lblBuilder.Set("job", "foo").Labels()
lblBuilder.Reset(nil)
jobBar := lblBuilder.Set("job", "bar").Labels()
require.Len(t, res.Msg.LabelsSet, 2)
require.Contains(t, res.Msg.LabelsSet, &typesv1.Labels{Labels: jobFoo})
require.Contains(t, res.Msg.LabelsSet, &typesv1.Labels{Labels: jobBar})

}

func TestHeadProfileTypes(t *testing.T) {
Expand Down
4 changes: 3 additions & 1 deletion pkg/querier/querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,13 @@ func (q *Querier) Series(ctx context.Context, req *connect.Request[querierv1.Ser

responses, err := forAllIngesters(ctx, q.ingesterQuerier, func(childCtx context.Context, ic IngesterQueryClient) ([]*typesv1.Labels, error) {
res, err := ic.Series(childCtx, connect.NewRequest(&ingestv1.SeriesRequest{
Matchers: req.Msg.Matchers,
Matchers: req.Msg.Matchers,
LabelNames: req.Msg.LabelNames,
simonswine marked this conversation as resolved.
Show resolved Hide resolved
}))
if err != nil {
return nil, err
}
// TODO: Remove this once we have the ingesters returning the filtered response, has been rolled out (f25).
simonswine marked this conversation as resolved.
Show resolved Hide resolved
filterSeriesByLabelNames(res.Msg.LabelsSet, labelNameMap)

return res.Msg.LabelsSet, nil
Expand Down