github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/storage/storage_labels.go (about)

     1  package storage
     2  
     3  import (
     4  	"context"
     5  	"sort"
     6  	"strings"
     7  
     8  	"github.com/pyroscope-io/pyroscope/pkg/flameql"
     9  	"github.com/pyroscope-io/pyroscope/pkg/storage/segment"
    10  	"github.com/pyroscope-io/pyroscope/pkg/util/slices"
    11  )
    12  
    13  //revive:disable-next-line:get-return callback is used
    14  func (s *Storage) GetKeys(_ context.Context, cb func(string) bool) { s.labels.GetKeys(cb) }
    15  
    16  //revive:disable-next-line:get-return callback is used
    17  func (s *Storage) GetValues(_ context.Context, key string, cb func(v string) bool) {
    18  	s.labels.GetValues(key, func(v string) bool {
    19  		if key != "__name__" || !slices.StringContains(s.config.hideApplications, v) {
    20  			return cb(v)
    21  		}
    22  		return true
    23  	})
    24  }
    25  
    26  func (s *Storage) GetKeysByQuery(_ context.Context, in GetLabelKeysByQueryInput) (GetLabelKeysByQueryOutput, error) {
    27  	var output GetLabelKeysByQueryOutput
    28  	parsedQuery, err := flameql.ParseQuery(in.Query)
    29  	if err != nil {
    30  		return output, err
    31  	}
    32  
    33  	segmentKey, err := segment.ParseKey(parsedQuery.AppName + "{}")
    34  	if err != nil {
    35  		return output, err
    36  	}
    37  	dimensionKeys := s.dimensionKeysByKey(segmentKey)
    38  
    39  	resultSet := map[string]bool{}
    40  	for _, dk := range dimensionKeys() {
    41  		dkParsed, _ := segment.ParseKey(string(dk))
    42  		if dkParsed.AppName() == parsedQuery.AppName {
    43  			for k := range dkParsed.Labels() {
    44  				resultSet[k] = true
    45  			}
    46  		}
    47  	}
    48  
    49  	for v := range resultSet {
    50  		output.Keys = append(output.Keys, v)
    51  	}
    52  
    53  	sort.Strings(output.Keys)
    54  	return output, nil
    55  }
    56  
    57  func (s *Storage) GetValuesByQuery(_ context.Context, in GetLabelValuesByQueryInput) (GetLabelValuesByQueryOutput, error) {
    58  	var output GetLabelValuesByQueryOutput
    59  	parsedQuery, err := flameql.ParseQuery(in.Query)
    60  	if err != nil {
    61  		return output, err
    62  	}
    63  
    64  	segmentKey, err := segment.ParseKey(parsedQuery.AppName + "{}")
    65  	if err != nil {
    66  		return output, err
    67  	}
    68  	dimensionKeys := s.dimensionKeysByKey(segmentKey)
    69  
    70  	resultSet := map[string]bool{}
    71  	for _, dk := range dimensionKeys() {
    72  		dkParsed, _ := segment.ParseKey(string(dk))
    73  		if v, ok := dkParsed.Labels()[in.Label]; ok {
    74  			resultSet[v] = true
    75  		}
    76  	}
    77  
    78  	for v := range resultSet {
    79  		output.Values = append(output.Values, v)
    80  	}
    81  
    82  	sort.Strings(output.Values)
    83  	return output, nil
    84  }
    85  
    86  // GetAppNames returns the list of all app's names
    87  // It works by querying the __name__ label
    88  func (s *Storage) GetAppNames(ctx context.Context) []string {
    89  	appNames := make([]string, 0)
    90  
    91  	s.GetValues(ctx, "__name__", func(v string) bool {
    92  		if strings.TrimSpace(v) != "" {
    93  			// skip empty app names
    94  			appNames = append(appNames, v)
    95  		}
    96  
    97  		return true
    98  	})
    99  
   100  	return appNames
   101  }