github.com/grafana/pyroscope@v1.18.0/pkg/featureflags/feature_flags.go (about) 1 package featureflags 2 3 import ( 4 "context" 5 "sort" 6 7 "connectrpc.com/connect" 8 "github.com/prometheus/client_golang/prometheus" 9 "github.com/prometheus/client_golang/prometheus/promauto" 10 11 capabilitiesv1 "github.com/grafana/pyroscope/api/gen/proto/go/capabilities/v1" 12 ) 13 14 const ( 15 V2StorageLayer = "v2StorageLayer" 16 PyroscopeRuler = "pyroscopeRuler" 17 PyroscopeRulerFunctions = "pyroscopeRulerFunctions" 18 UTF8LabelNames = "utf8LabelNames" 19 ) 20 21 func stringPtr(s string) *string { 22 return &s 23 } 24 25 var ( 26 allFeatureFlags = map[string]*capabilitiesv1.FeatureFlag{ 27 V2StorageLayer: { 28 Enabled: false, 29 Description: stringPtr("v2 storage layer"), 30 DocumentationUrl: stringPtr("https://github.com/grafana/pyroscope/blob/main/pkg/pyroscope/PYROSCOPE_V2.md"), 31 }, 32 PyroscopeRuler: { 33 Enabled: false, 34 Description: stringPtr("Supports the Pyroscope ruler, which exports Prometheus metrics from Profiling Data."), 35 }, 36 PyroscopeRulerFunctions: { 37 Enabled: false, 38 Description: stringPtr("Enables function support for the Pyroscope ruler, which allows to export resource usage on a per function level."), 39 }, 40 UTF8LabelNames: { 41 Enabled: false, 42 Description: stringPtr("Supports UTF-8 label names for Pyroscope read/write APIs."), 43 }, 44 } 45 ) 46 47 type FeatureFlags struct { 48 flags []*capabilitiesv1.FeatureFlag 49 infoMetric *prometheus.GaugeVec 50 } 51 52 func (h *FeatureFlags) GetFeatureFlags( 53 ctx context.Context, 54 req *connect.Request[capabilitiesv1.GetFeatureFlagsRequest], 55 ) (*connect.Response[capabilitiesv1.GetFeatureFlagsResponse], error) { 56 return &connect.Response[capabilitiesv1.GetFeatureFlagsResponse]{ 57 Msg: &capabilitiesv1.GetFeatureFlagsResponse{ 58 FeatureFlags: h.flags, 59 }, 60 }, nil 61 } 62 63 func boolToFloat64(b bool) float64 { 64 if b { 65 return 1.0 66 } 67 return 0.0 68 } 69 70 func NewFromEnabled(reg prometheus.Registerer, enabled map[string]bool) *FeatureFlags { 71 ff := &FeatureFlags{ 72 infoMetric: promauto.With(reg).NewGaugeVec(prometheus.GaugeOpts{ 73 Name: "pyroscope_feature_flags_enabled", 74 Help: "Shows the global feature flags", 75 }, []string{"name"}), 76 } 77 78 ff.flags = make([]*capabilitiesv1.FeatureFlag, 0, len(allFeatureFlags)) 79 for name, flag := range allFeatureFlags { 80 flag := flag.CloneVT() 81 flag.Name = name 82 ff.flags = append(ff.flags, flag) 83 flag.Enabled = enabled[name] 84 enabled[name] = true 85 ff.infoMetric.WithLabelValues(flag.Name).Set(boolToFloat64(flag.Enabled)) 86 } 87 sort.Slice(ff.flags, func(i, j int) bool { 88 return ff.flags[i].Name < ff.flags[j].Name 89 90 }) 91 92 return ff 93 }