github.com/grafana/pyroscope@v1.18.0/pkg/frontend/readpath/queryfrontend/query_label_names.go (about) 1 package queryfrontend 2 3 import ( 4 "context" 5 6 "connectrpc.com/connect" 7 "github.com/go-kit/log/level" 8 "github.com/grafana/dskit/tenant" 9 10 queryv1 "github.com/grafana/pyroscope/api/gen/proto/go/query/v1" 11 typesv1 "github.com/grafana/pyroscope/api/gen/proto/go/types/v1" 12 "github.com/grafana/pyroscope/pkg/featureflags" 13 "github.com/grafana/pyroscope/pkg/validation" 14 ) 15 16 func (q *QueryFrontend) LabelNames( 17 ctx context.Context, 18 c *connect.Request[typesv1.LabelNamesRequest], 19 ) (*connect.Response[typesv1.LabelNamesResponse], error) { 20 tenantIDs, err := tenant.TenantIDs(ctx) 21 if err != nil { 22 return nil, connect.NewError(connect.CodeInvalidArgument, err) 23 } 24 empty, err := validation.SanitizeTimeRange(q.limits, tenantIDs, &c.Msg.Start, &c.Msg.End) 25 if err != nil { 26 return nil, connect.NewError(connect.CodeInvalidArgument, err) 27 } 28 if empty { 29 return connect.NewResponse(&typesv1.LabelNamesResponse{}), nil 30 } 31 32 labelSelector, err := buildLabelSelectorFromMatchers(c.Msg.Matchers) 33 if err != nil { 34 return nil, connect.NewError(connect.CodeInvalidArgument, err) 35 } 36 report, err := q.querySingle(ctx, &queryv1.QueryRequest{ 37 StartTime: c.Msg.Start, 38 EndTime: c.Msg.End, 39 LabelSelector: labelSelector, 40 Query: []*queryv1.Query{{ 41 QueryType: queryv1.QueryType_QUERY_LABEL_NAMES, 42 LabelNames: &queryv1.LabelNamesQuery{}, 43 }}, 44 }) 45 if err != nil { 46 return nil, err 47 } 48 if report == nil { 49 return connect.NewResponse(&typesv1.LabelNamesResponse{}), nil 50 } 51 52 labelNames := report.LabelNames.LabelNames 53 if capabilities, ok := featureflags.GetClientCapabilities(ctx); !ok || !capabilities.AllowUtf8LabelNames { 54 // Filter out label names not passing legacy validation if utf8 label names not enabled 55 filteredLabelNames := make([]string, 0, len(labelNames)) 56 for _, labelName := range labelNames { 57 if _, _, ok := validation.SanitizeLegacyLabelName(labelName); !ok { 58 level.Debug(q.logger).Log("msg", "filtering out label", "label_name", labelName) 59 continue 60 } 61 filteredLabelNames = append(filteredLabelNames, labelName) 62 } 63 labelNames = filteredLabelNames 64 } 65 66 return connect.NewResponse(&typesv1.LabelNamesResponse{Names: labelNames}), nil 67 }