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 }