github.com/grafana/pyroscope@v1.18.0/pkg/frontend/readpath/queryfrontend/query_label_values.go (about) 1 package queryfrontend 2 3 import ( 4 "context" 5 6 "connectrpc.com/connect" 7 "github.com/grafana/dskit/tenant" 8 "github.com/pkg/errors" 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/validation" 13 ) 14 15 func (q *QueryFrontend) LabelValues( 16 ctx context.Context, 17 c *connect.Request[typesv1.LabelValuesRequest], 18 ) (*connect.Response[typesv1.LabelValuesResponse], error) { 19 tenantIDs, err := tenant.TenantIDs(ctx) 20 if err != nil { 21 return nil, connect.NewError(connect.CodeInvalidArgument, err) 22 } 23 empty, err := validation.SanitizeTimeRange(q.limits, tenantIDs, &c.Msg.Start, &c.Msg.End) 24 if err != nil { 25 return nil, connect.NewError(connect.CodeInvalidArgument, err) 26 } 27 if empty { 28 return connect.NewResponse(&typesv1.LabelValuesResponse{}), nil 29 } 30 31 if c.Msg.Name == "" { 32 return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("name is required")) 33 } 34 35 labelSelector, err := buildLabelSelectorFromMatchers(c.Msg.Matchers) 36 if err != nil { 37 return nil, connect.NewError(connect.CodeInvalidArgument, err) 38 } 39 report, err := q.querySingle(ctx, &queryv1.QueryRequest{ 40 StartTime: c.Msg.Start, 41 EndTime: c.Msg.End, 42 LabelSelector: labelSelector, 43 Query: []*queryv1.Query{{ 44 QueryType: queryv1.QueryType_QUERY_LABEL_VALUES, 45 LabelValues: &queryv1.LabelValuesQuery{LabelName: c.Msg.Name}, 46 }}, 47 }) 48 if err != nil { 49 return nil, err 50 } 51 if report == nil { 52 return connect.NewResponse(&typesv1.LabelValuesResponse{}), nil 53 } 54 return connect.NewResponse(&typesv1.LabelValuesResponse{Names: report.LabelValues.LabelValues}), nil 55 }