The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/featuremgmt/service.go

81 lines
2.1 KiB

package featuremgmt
import (
"sort"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"golang.org/x/exp/maps"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/setting"
)
var (
// The values are updated each time
featureToggleInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: "feature_toggles_info",
Help: "info metric that exposes what feature toggles are enabled or not",
Namespace: "grafana",
}, []string{"name"})
)
func ProvideManagerService(cfg *setting.Cfg) (*FeatureManager, error) {
mgmt := &FeatureManager{
isDevMod: cfg.Env != setting.Prod,
flags: make(map[string]*FeatureFlag, 30),
enabled: make(map[string]bool),
startup: make(map[string]bool),
warnings: make(map[string]string),
Settings: cfg.FeatureManagement,
log: log.New("featuremgmt"),
}
// Register the standard flags
mgmt.registerFlags(standardFeatureFlags...)
// Load the flags from `custom.ini` files
flags, err := setting.ReadFeatureTogglesFromInitFile(cfg.Raw.Section("feature_toggles"))
if err != nil {
return mgmt, err
}
for key, val := range flags {
_, ok := mgmt.flags[key]
if !ok {
switch key {
// renamed the flag so it supports more panels
case "autoMigrateGraphPanels":
key = FlagAutoMigrateOldPanels
default:
mgmt.flags[key] = &FeatureFlag{
Name: key,
Stage: FeatureStageUnknown,
}
mgmt.warnings[key] = "unknown flag in config"
}
}
mgmt.startup[key] = val
}
// update the values
mgmt.update()
// Log the enabled feature toggles at startup
enabled := sort.StringSlice(maps.Keys(mgmt.enabled))
logctx := make([]any, len(enabled)*2)
for i, k := range enabled {
logctx[(i * 2)] = k
logctx[(i*2)+1] = true
}
mgmt.log.Info("FeatureToggles", logctx...)
// Minimum approach to avoid circular dependency
// nolint:staticcheck
cfg.IsFeatureToggleEnabled = mgmt.IsEnabledGlobally
return mgmt, nil
}
// ProvideToggles allows read-only access to the feature state
func ProvideToggles(mgmt *FeatureManager) FeatureToggles {
return mgmt
}