mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 05:19:25 +08:00
Plugins: Enable feature toggle pluginsDynamicAngularDetectionPatterns
by default (#84723)
* Enable feature toggle pluginsDynamicAngularDetectionPatterns by default * Change backgroundJobInterval to 24h * re-generate feature toggles * Use different intervals for cloud vs on-prem * temporarily switch interval log to info level * debug level again * Simplify provideDynamic for tests * re-generated feature toggles files * PR review feedback * PR review feedback: removed dependency from plugin management config
This commit is contained in:
@ -19,41 +19,42 @@ This page contains a list of available feature toggles. To learn how to turn on
|
||||
|
||||
Some features are enabled by default. You can disable these feature by setting the feature flag to "false" in the configuration.
|
||||
|
||||
| Feature toggle name | Description | Enabled by default |
|
||||
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
||||
| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | |
|
||||
| `publicDashboards` | [Deprecated] Public dashboards are now enabled by default; to disable them, use the configuration setting. This feature toggle will be removed in the next major version. | Yes |
|
||||
| `featureHighlights` | Highlight Grafana Enterprise features | |
|
||||
| `correlations` | Correlations page | |
|
||||
| `exploreContentOutline` | Content outline sidebar | Yes |
|
||||
| `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes |
|
||||
| `nestedFolderPicker` | Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle | Yes |
|
||||
| `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes |
|
||||
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes |
|
||||
| `prometheusMetricEncyclopedia` | Adds the metrics explorer component to the Prometheus query builder as an option in metric select | Yes |
|
||||
| `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes |
|
||||
| `prometheusDataplane` | Changes responses to from Prometheus to be compliant with the dataplane specification. In particular, when this feature toggle is active, the numeric `Field.Name` is set from 'Value' to the value of the `__name__` label. | Yes |
|
||||
| `lokiMetricDataplane` | Changes metric responses from Loki to be compliant with the dataplane specification. | Yes |
|
||||
| `dataplaneFrontendFallback` | Support dataplane contract field name change for transformations and field name matchers where the name is different | Yes |
|
||||
| `enableElasticsearchBackendQuerying` | Enable the processing of queries and responses in the Elasticsearch data source through backend | Yes |
|
||||
| `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes |
|
||||
| `logsExploreTableVisualisation` | A table visualisation for logs in Explore | Yes |
|
||||
| `transformationsRedesign` | Enables the transformations redesign | Yes |
|
||||
| `traceQLStreaming` | Enables response streaming of TraceQL queries of the Tempo data source | |
|
||||
| `awsAsyncQueryCaching` | Enable caching for async queries for Redshift and Athena. Requires that the datasource has caching and async query support enabled | Yes |
|
||||
| `prometheusConfigOverhaulAuth` | Update the Prometheus configuration page with the new auth component | Yes |
|
||||
| `influxdbSqlSupport` | Enable InfluxDB SQL query language support with new querying UI | Yes |
|
||||
| `alertingNoDataErrorExecution` | Changes how Alerting state manager handles execution of NoData/Error | Yes |
|
||||
| `angularDeprecationUI` | Display Angular warnings in dashboards and panels | Yes |
|
||||
| `alertingInsights` | Show the new alerting insights landing page | Yes |
|
||||
| `panelMonitoring` | Enables panel monitoring through logs and measurements | Yes |
|
||||
| `recoveryThreshold` | Enables feature recovery threshold (aka hysteresis) for threshold server-side expression | Yes |
|
||||
| `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes |
|
||||
| `managedPluginsInstall` | Install managed plugins directly from plugins catalog | Yes |
|
||||
| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes |
|
||||
| `lokiQueryHints` | Enables query hints for Loki | Yes |
|
||||
| `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | |
|
||||
| `betterPageScrolling` | Removes CustomScrollbar from the UI, relying on native browser scrollbars | Yes |
|
||||
| Feature toggle name | Description | Enabled by default |
|
||||
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
|
||||
| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | |
|
||||
| `publicDashboards` | [Deprecated] Public dashboards are now enabled by default; to disable them, use the configuration setting. This feature toggle will be removed in the next major version. | Yes |
|
||||
| `featureHighlights` | Highlight Grafana Enterprise features | |
|
||||
| `correlations` | Correlations page | |
|
||||
| `exploreContentOutline` | Content outline sidebar | Yes |
|
||||
| `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes |
|
||||
| `nestedFolderPicker` | Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle | Yes |
|
||||
| `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes |
|
||||
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes |
|
||||
| `prometheusMetricEncyclopedia` | Adds the metrics explorer component to the Prometheus query builder as an option in metric select | Yes |
|
||||
| `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes |
|
||||
| `prometheusDataplane` | Changes responses to from Prometheus to be compliant with the dataplane specification. In particular, when this feature toggle is active, the numeric `Field.Name` is set from 'Value' to the value of the `__name__` label. | Yes |
|
||||
| `lokiMetricDataplane` | Changes metric responses from Loki to be compliant with the dataplane specification. | Yes |
|
||||
| `dataplaneFrontendFallback` | Support dataplane contract field name change for transformations and field name matchers where the name is different | Yes |
|
||||
| `enableElasticsearchBackendQuerying` | Enable the processing of queries and responses in the Elasticsearch data source through backend | Yes |
|
||||
| `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes |
|
||||
| `pluginsDynamicAngularDetectionPatterns` | Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones | Yes |
|
||||
| `logsExploreTableVisualisation` | A table visualisation for logs in Explore | Yes |
|
||||
| `transformationsRedesign` | Enables the transformations redesign | Yes |
|
||||
| `traceQLStreaming` | Enables response streaming of TraceQL queries of the Tempo data source | |
|
||||
| `awsAsyncQueryCaching` | Enable caching for async queries for Redshift and Athena. Requires that the datasource has caching and async query support enabled | Yes |
|
||||
| `prometheusConfigOverhaulAuth` | Update the Prometheus configuration page with the new auth component | Yes |
|
||||
| `influxdbSqlSupport` | Enable InfluxDB SQL query language support with new querying UI | Yes |
|
||||
| `alertingNoDataErrorExecution` | Changes how Alerting state manager handles execution of NoData/Error | Yes |
|
||||
| `angularDeprecationUI` | Display Angular warnings in dashboards and panels | Yes |
|
||||
| `alertingInsights` | Show the new alerting insights landing page | Yes |
|
||||
| `panelMonitoring` | Enables panel monitoring through logs and measurements | Yes |
|
||||
| `recoveryThreshold` | Enables feature recovery threshold (aka hysteresis) for threshold server-side expression | Yes |
|
||||
| `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes |
|
||||
| `managedPluginsInstall` | Install managed plugins directly from plugins catalog | Yes |
|
||||
| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes |
|
||||
| `lokiQueryHints` | Enables query hints for Loki | Yes |
|
||||
| `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | |
|
||||
| `betterPageScrolling` | Removes CustomScrollbar from the UI, relying on native browser scrollbars | Yes |
|
||||
|
||||
## Preview feature toggles
|
||||
|
||||
@ -130,7 +131,6 @@ Experimental features might be changed or removed without prior notice.
|
||||
| `dashboardEmbed` | Allow embedding dashboard for external use in Code editors |
|
||||
| `frontendSandboxMonitorOnly` | Enables monitor only in the plugin frontend sandbox (if enabled) |
|
||||
| `lokiFormatQuery` | Enables the ability to format Loki queries |
|
||||
| `pluginsDynamicAngularDetectionPatterns` | Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones |
|
||||
| `vizAndWidgetSplit` | Split panels between visualizations and widgets |
|
||||
| `prometheusIncrementalQueryInstrumentation` | Adds RudderStack events to incremental queries |
|
||||
| `awsDatasourcesTempCredentials` | Support temporary security credentials in AWS plugins for Grafana Cloud customers |
|
||||
|
@ -510,9 +510,10 @@ var (
|
||||
{
|
||||
Name: "pluginsDynamicAngularDetectionPatterns",
|
||||
Description: "Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones",
|
||||
Stage: FeatureStageExperimental,
|
||||
Stage: FeatureStageGeneralAvailability,
|
||||
FrontendOnly: false,
|
||||
Owner: grafanaPluginsPlatformSquad,
|
||||
Expression: "true", // enabled by default
|
||||
},
|
||||
{
|
||||
Name: "vizAndWidgetSplit",
|
||||
|
@ -67,7 +67,7 @@ frontendSandboxMonitorOnly,experimental,@grafana/plugins-platform-backend,false,
|
||||
sqlDatasourceDatabaseSelection,preview,@grafana/dataviz-squad,false,false,true
|
||||
lokiFormatQuery,experimental,@grafana/observability-logs,false,false,true
|
||||
recordedQueriesMulti,GA,@grafana/observability-metrics,false,false,false
|
||||
pluginsDynamicAngularDetectionPatterns,experimental,@grafana/plugins-platform-backend,false,false,false
|
||||
pluginsDynamicAngularDetectionPatterns,GA,@grafana/plugins-platform-backend,false,false,false
|
||||
vizAndWidgetSplit,experimental,@grafana/dashboards-squad,false,false,true
|
||||
prometheusIncrementalQueryInstrumentation,experimental,@grafana/observability-metrics,false,false,true
|
||||
logsExploreTableVisualisation,GA,@grafana/observability-logs,false,false,true
|
||||
|
|
@ -441,12 +441,15 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "pluginsDynamicAngularDetectionPatterns",
|
||||
"resourceVersion": "1709648236447",
|
||||
"creationTimestamp": "2024-03-05T14:17:16Z"
|
||||
"resourceVersion": "1710847676897",
|
||||
"creationTimestamp": "2024-03-05T14:17:16Z",
|
||||
"annotations": {
|
||||
"grafana.app/updatedTimestamp": "2024-03-19 11:27:56.897962695 +0000 UTC"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"description": "Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones",
|
||||
"stage": "experimental",
|
||||
"stage": "GA",
|
||||
"codeowner": "@grafana/plugins-platform-backend"
|
||||
}
|
||||
},
|
||||
|
@ -12,18 +12,21 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/log"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
var errNotModified = errors.New("not modified")
|
||||
|
||||
// backgroundJobInterval is the interval that passes between background job runs.
|
||||
// It can be overwritten in tests.
|
||||
var backgroundJobInterval = time.Hour * 1
|
||||
// Intervals that passes between background job runs.
|
||||
// Can be overwritten in tests.
|
||||
var (
|
||||
backgroundJobIntervalOnPrem = time.Hour * 24
|
||||
backgroundJobIntervalCloud = time.Hour * 1
|
||||
)
|
||||
|
||||
// Dynamic is an angulardetector.DetectorsProvider that calls GCOM to get Angular detection patterns,
|
||||
// converts them to detectors and caches them for all future calls.
|
||||
@ -45,20 +48,32 @@ type Dynamic struct {
|
||||
|
||||
// mux is the mutex used to read/write the cached detectors in a concurrency-safe way.
|
||||
mux sync.RWMutex
|
||||
|
||||
// backgroundJobInterval is the interval that passes between background job runs.
|
||||
backgroundJobInterval time.Duration
|
||||
}
|
||||
|
||||
func ProvideDynamic(cfg *config.PluginManagementCfg, store angularpatternsstore.Service, features featuremgmt.FeatureToggles) (*Dynamic, error) {
|
||||
func ProvideDynamic(cfg *setting.Cfg, store angularpatternsstore.Service, features featuremgmt.FeatureToggles) (*Dynamic, error) {
|
||||
backgroundJobInterval := backgroundJobIntervalOnPrem
|
||||
if cfg.StackID != "" {
|
||||
// Use a shorter interval for cloud.
|
||||
// (in cloud, cfg.StackID is always set).
|
||||
backgroundJobInterval = backgroundJobIntervalCloud
|
||||
}
|
||||
|
||||
d := &Dynamic{
|
||||
log: log.New("plugin.angulardetectorsprovider.dynamic"),
|
||||
features: features,
|
||||
store: store,
|
||||
httpClient: makeHttpClient(),
|
||||
baseURL: cfg.GrafanaComURL,
|
||||
log: log.New("plugin.angulardetectorsprovider.dynamic"),
|
||||
features: features,
|
||||
store: store,
|
||||
httpClient: makeHttpClient(),
|
||||
baseURL: cfg.GrafanaComURL,
|
||||
backgroundJobInterval: backgroundJobInterval,
|
||||
}
|
||||
if d.IsDisabled() {
|
||||
// Do not attempt to restore if the background service is disabled (no feature flag)
|
||||
return d, nil
|
||||
}
|
||||
d.log.Debug("Providing dynamic angular detection patterns", "baseURL", d.baseURL, "interval", d.backgroundJobInterval)
|
||||
|
||||
// Perform the initial restore from db
|
||||
st := time.Now()
|
||||
@ -224,7 +239,7 @@ func (d *Dynamic) IsDisabled() bool {
|
||||
}
|
||||
|
||||
// randomSkew returns a random time.Duration between 0 and maxSkew.
|
||||
// This can be added to backgroundJobInterval to skew it by a random amount.
|
||||
// This can be added to d.backgroundJobInterval to skew it by a random amount.
|
||||
func (d *Dynamic) randomSkew(maxSkew time.Duration) time.Duration {
|
||||
return time.Duration(rand.Float64() * float64(maxSkew))
|
||||
}
|
||||
@ -242,15 +257,15 @@ func (d *Dynamic) Run(ctx context.Context) error {
|
||||
// Offset the background job interval a bit to skew GCOM calls from all instances,
|
||||
// so GCOM is not overwhelmed with lots of requests all at the same time.
|
||||
// Important when lots of HG instances restart at the same time.
|
||||
skew := d.randomSkew(backgroundJobInterval / 4)
|
||||
backgroundJobInterval += skew
|
||||
skew := d.randomSkew(d.backgroundJobInterval / 4)
|
||||
d.backgroundJobInterval += skew
|
||||
d.log.Debug(
|
||||
"Applied background job skew",
|
||||
"skew", backgroundJobInterval, "interval", backgroundJobInterval,
|
||||
"skew", d.backgroundJobInterval, "interval", d.backgroundJobInterval,
|
||||
)
|
||||
|
||||
nextRunUntil := time.Until(lastUpdate.Add(backgroundJobInterval))
|
||||
ticker := time.NewTicker(backgroundJobInterval)
|
||||
nextRunUntil := time.Until(lastUpdate.Add(d.backgroundJobInterval))
|
||||
ticker := time.NewTicker(d.backgroundJobInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
var tick <-chan time.Time
|
||||
@ -286,7 +301,7 @@ func (d *Dynamic) Run(ctx context.Context) error {
|
||||
d.log.Info("Patterns update finished", "duration", time.Since(st))
|
||||
|
||||
// Restore default ticker if we run with a shorter interval the first time
|
||||
ticker.Reset(backgroundJobInterval)
|
||||
ticker.Reset(d.backgroundJobInterval)
|
||||
tick = ticker.C
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
|
@ -14,10 +14,10 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/kvstore"
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func TestDynamicAngularDetectorsProvider(t *testing.T) {
|
||||
@ -314,6 +314,22 @@ func TestDynamicAngularDetectorsProvider(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestDynamicAngularDetectorsProviderCloudVsOnPrem(t *testing.T) {
|
||||
gcom := newDefaultGCOMScenario()
|
||||
srv := gcom.newHTTPTestServer()
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
t.Run("should use cloud interval if stack_id is set", func(t *testing.T) {
|
||||
svc := provideDynamic(t, srv.URL, provideDynamicOpts{cfg: &setting.Cfg{StackID: "1234"}})
|
||||
require.Equal(t, backgroundJobIntervalCloud, svc.backgroundJobInterval)
|
||||
})
|
||||
|
||||
t.Run("should use on-prem interval if stack_id is not set", func(t *testing.T) {
|
||||
svc := provideDynamic(t, srv.URL, provideDynamicOpts{cfg: &setting.Cfg{StackID: ""}})
|
||||
require.Equal(t, backgroundJobIntervalOnPrem, svc.backgroundJobInterval)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDynamicAngularDetectorsProviderBackgroundService(t *testing.T) {
|
||||
mockGCOMPatterns := newMockGCOMPatterns()
|
||||
gcom := newDefaultGCOMScenario()
|
||||
@ -321,10 +337,10 @@ func TestDynamicAngularDetectorsProviderBackgroundService(t *testing.T) {
|
||||
t.Cleanup(srv.Close)
|
||||
|
||||
t.Run("background service", func(t *testing.T) {
|
||||
oldBackgroundJobInterval := backgroundJobInterval
|
||||
backgroundJobInterval = time.Millisecond * 500
|
||||
oldBackgroundJobInterval := backgroundJobIntervalOnPrem
|
||||
backgroundJobIntervalOnPrem = time.Millisecond * 500
|
||||
t.Cleanup(func() {
|
||||
backgroundJobInterval = oldBackgroundJobInterval
|
||||
backgroundJobIntervalOnPrem = oldBackgroundJobInterval
|
||||
})
|
||||
|
||||
t.Run("is disabled if feature flag is not present", func(t *testing.T) {
|
||||
@ -563,6 +579,7 @@ func newError500GCOMScenario() *gcomScenario {
|
||||
|
||||
type provideDynamicOpts struct {
|
||||
store angularpatternsstore.Service
|
||||
cfg *setting.Cfg
|
||||
}
|
||||
|
||||
func provideDynamic(t *testing.T, gcomURL string, opts ...provideDynamicOpts) *Dynamic {
|
||||
@ -573,8 +590,12 @@ func provideDynamic(t *testing.T, gcomURL string, opts ...provideDynamicOpts) *D
|
||||
if opt.store == nil {
|
||||
opt.store = angularpatternsstore.ProvideService(kvstore.NewFakeKVStore())
|
||||
}
|
||||
if opt.cfg == nil {
|
||||
opt.cfg = setting.NewCfg()
|
||||
}
|
||||
opt.cfg.GrafanaComURL = gcomURL
|
||||
d, err := ProvideDynamic(
|
||||
&config.PluginManagementCfg{GrafanaComURL: gcomURL},
|
||||
opt.cfg,
|
||||
opt.store,
|
||||
featuremgmt.WithFeatures(featuremgmt.FlagPluginsDynamicAngularDetectionPatterns),
|
||||
)
|
||||
|
@ -7,19 +7,19 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/kvstore"
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/angulardetectorsprovider"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func TestProvideService(t *testing.T) {
|
||||
t.Run("uses hardcoded inspector if feature flag is not present", func(t *testing.T) {
|
||||
features := featuremgmt.WithFeatures()
|
||||
dynamic, err := angulardetectorsprovider.ProvideDynamic(
|
||||
&config.PluginManagementCfg{},
|
||||
setting.NewCfg(),
|
||||
angularpatternsstore.ProvideService(kvstore.NewFakeKVStore()),
|
||||
features,
|
||||
)
|
||||
@ -37,7 +37,7 @@ func TestProvideService(t *testing.T) {
|
||||
featuremgmt.FlagPluginsDynamicAngularDetectionPatterns,
|
||||
)
|
||||
dynamic, err := angulardetectorsprovider.ProvideDynamic(
|
||||
&config.PluginManagementCfg{},
|
||||
setting.NewCfg(),
|
||||
angularpatternsstore.ProvideService(kvstore.NewFakeKVStore()),
|
||||
features,
|
||||
)
|
||||
|
Reference in New Issue
Block a user