github.com/grafana/pyroscope@v1.18.0/pkg/frontend/readpath/queryfrontend/query_select_time_series.go (about) 1 package queryfrontend 2 3 import ( 4 "context" 5 "time" 6 7 "connectrpc.com/connect" 8 "github.com/grafana/dskit/tenant" 9 "github.com/pkg/errors" 10 11 querierv1 "github.com/grafana/pyroscope/api/gen/proto/go/querier/v1" 12 queryv1 "github.com/grafana/pyroscope/api/gen/proto/go/query/v1" 13 phlaremodel "github.com/grafana/pyroscope/pkg/model" 14 "github.com/grafana/pyroscope/pkg/validation" 15 ) 16 17 func (q *QueryFrontend) SelectSeries( 18 ctx context.Context, 19 c *connect.Request[querierv1.SelectSeriesRequest], 20 ) (*connect.Response[querierv1.SelectSeriesResponse], error) { 21 tenantIDs, err := tenant.TenantIDs(ctx) 22 if err != nil { 23 return nil, connect.NewError(connect.CodeInvalidArgument, err) 24 } 25 empty, err := validation.SanitizeTimeRange(q.limits, tenantIDs, &c.Msg.Start, &c.Msg.End) 26 if err != nil { 27 return nil, connect.NewError(connect.CodeInvalidArgument, err) 28 } 29 if empty { 30 return connect.NewResponse(&querierv1.SelectSeriesResponse{}), nil 31 } 32 33 _, err = phlaremodel.ParseProfileTypeSelector(c.Msg.ProfileTypeID) 34 if err != nil { 35 return nil, connect.NewError(connect.CodeInvalidArgument, err) 36 } 37 38 if c.Msg.Step == 0 { 39 return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("step must be non-zero")) 40 } 41 42 stepMs := time.Duration(c.Msg.Step * float64(time.Second)).Milliseconds() 43 start := c.Msg.Start - stepMs 44 45 labelSelector, err := buildLabelSelectorWithProfileType(c.Msg.LabelSelector, c.Msg.ProfileTypeID) 46 if err != nil { 47 return nil, connect.NewError(connect.CodeInvalidArgument, err) 48 } 49 report, err := q.querySingle(ctx, &queryv1.QueryRequest{ 50 StartTime: start, 51 EndTime: c.Msg.End, 52 LabelSelector: labelSelector, 53 Query: []*queryv1.Query{{ 54 QueryType: queryv1.QueryType_QUERY_TIME_SERIES, 55 TimeSeries: &queryv1.TimeSeriesQuery{ 56 Step: c.Msg.GetStep(), 57 GroupBy: c.Msg.GetGroupBy(), 58 Limit: c.Msg.GetLimit(), 59 ExemplarType: c.Msg.GetExemplarType(), 60 }, 61 }}, 62 }) 63 if err != nil { 64 return nil, err 65 } 66 if report == nil { 67 return connect.NewResponse(&querierv1.SelectSeriesResponse{}), nil 68 } 69 series := phlaremodel.TopSeries(report.TimeSeries.TimeSeries, int(c.Msg.GetLimit())) 70 return connect.NewResponse(&querierv1.SelectSeriesResponse{Series: series}), nil 71 }