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  }