mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Live: remove feature toggle and enable by default (#33654)
This commit is contained in:
parent
9315152d4f
commit
33e4f8d7ac
@ -44,7 +44,6 @@ export enum GrafanaEdition {
|
|||||||
export interface FeatureToggles {
|
export interface FeatureToggles {
|
||||||
[name: string]: boolean;
|
[name: string]: boolean;
|
||||||
|
|
||||||
live: boolean;
|
|
||||||
ngalert: boolean;
|
ngalert: boolean;
|
||||||
trimDefaults: boolean;
|
trimDefaults: boolean;
|
||||||
panelLibrary: boolean;
|
panelLibrary: boolean;
|
||||||
|
@ -53,7 +53,6 @@ export class GrafanaBootConfig implements GrafanaConfig {
|
|||||||
theme2: GrafanaTheme2;
|
theme2: GrafanaTheme2;
|
||||||
pluginsToPreload: string[] = [];
|
pluginsToPreload: string[] = [];
|
||||||
featureToggles: FeatureToggles = {
|
featureToggles: FeatureToggles = {
|
||||||
live: false,
|
|
||||||
meta: false,
|
meta: false,
|
||||||
ngalert: false,
|
ngalert: false,
|
||||||
panelLibrary: false,
|
panelLibrary: false,
|
||||||
|
@ -413,21 +413,19 @@ func (hs *HTTPServer) registerRoutes() {
|
|||||||
|
|
||||||
apiRoute.Post("/frontend-metrics", bind(metrics.PostFrontendMetricsCommand{}), routing.Wrap(hs.PostFrontendMetrics))
|
apiRoute.Post("/frontend-metrics", bind(metrics.PostFrontendMetricsCommand{}), routing.Wrap(hs.PostFrontendMetrics))
|
||||||
|
|
||||||
if hs.Live.IsEnabled() {
|
apiRoute.Group("/live", func(liveRoute routing.RouteRegister) {
|
||||||
apiRoute.Group("/live", func(liveRoute routing.RouteRegister) {
|
// the channel path is in the name
|
||||||
// the channel path is in the name
|
liveRoute.Post("/publish", bind(dtos.LivePublishCmd{}), routing.Wrap(hs.Live.HandleHTTPPublish))
|
||||||
liveRoute.Post("/publish", bind(dtos.LivePublishCmd{}), routing.Wrap(hs.Live.HandleHTTPPublish))
|
|
||||||
|
|
||||||
// POST influx line protocol
|
// POST influx line protocol
|
||||||
liveRoute.Post("/push/:streamId", hs.LivePushGateway.Handle)
|
liveRoute.Post("/push/:streamId", hs.LivePushGateway.Handle)
|
||||||
|
|
||||||
// List available streams and fields
|
// List available streams and fields
|
||||||
liveRoute.Get("/list", routing.Wrap(hs.Live.HandleListHTTP))
|
liveRoute.Get("/list", routing.Wrap(hs.Live.HandleListHTTP))
|
||||||
|
|
||||||
// Some channels may have info
|
// Some channels may have info
|
||||||
liveRoute.Get("/info/*", routing.Wrap(hs.Live.HandleInfoHTTP))
|
liveRoute.Get("/info/*", routing.Wrap(hs.Live.HandleInfoHTTP))
|
||||||
})
|
})
|
||||||
}
|
|
||||||
|
|
||||||
// short urls
|
// short urls
|
||||||
apiRoute.Post("/short-urls", bind(dtos.CreateShortURLCmd{}), routing.Wrap(hs.createShortURL))
|
apiRoute.Post("/short-urls", bind(dtos.CreateShortURLCmd{}), routing.Wrap(hs.createShortURL))
|
||||||
|
@ -270,8 +270,8 @@ func (hs *HTTPServer) deleteDashboard(c *models.ReqContext) response.Response {
|
|||||||
return response.Error(500, "Failed to delete dashboard", err)
|
return response.Error(500, "Failed to delete dashboard", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if hs.Live.IsEnabled() {
|
if hs.Live != nil {
|
||||||
err := hs.Live.GrafanaScope.Dashboards.DashboardDeleted(c.ToUserDisplayDTO(), dash.Uid)
|
err = hs.Live.GrafanaScope.Dashboards.DashboardDeleted(c.ToUserDisplayDTO(), dash.Uid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hs.log.Error("Failed to broadcast delete info", "dashboard", dash.Uid, "error", err)
|
hs.log.Error("Failed to broadcast delete info", "dashboard", dash.Uid, "error", err)
|
||||||
}
|
}
|
||||||
@ -337,8 +337,8 @@ func (hs *HTTPServer) PostDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
|||||||
dashSvc := dashboards.NewService(hs.SQLStore)
|
dashSvc := dashboards.NewService(hs.SQLStore)
|
||||||
dashboard, err := dashSvc.SaveDashboard(dashItem, allowUiUpdate)
|
dashboard, err := dashSvc.SaveDashboard(dashItem, allowUiUpdate)
|
||||||
|
|
||||||
// Tell everyone listening that the dashboard changed
|
if hs.Live != nil {
|
||||||
if hs.Live.IsEnabled() {
|
// Tell everyone listening that the dashboard changed
|
||||||
if dashboard == nil {
|
if dashboard == nil {
|
||||||
dashboard = dash // the original request
|
dashboard = dash // the original request
|
||||||
}
|
}
|
||||||
@ -360,6 +360,7 @@ func (hs *HTTPServer) PostDashboard(c *models.ReqContext, cmd models.SaveDashboa
|
|||||||
hs.log.Warn("unable to broadcast save event", "uid", dashboard.Uid, "error", err)
|
hs.log.Warn("unable to broadcast save event", "uid", dashboard.Uid, "error", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return hs.dashboardSaveErrorToApiResponse(err)
|
return hs.dashboardSaveErrorToApiResponse(err)
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,14 @@ type testState struct {
|
|||||||
dashQueries []*models.GetDashboardQuery
|
dashQueries []*models.GetDashboardQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newTestLive(t *testing.T) *live.GrafanaLive {
|
||||||
|
gLive := live.NewGrafanaLive()
|
||||||
|
gLive.RouteRegister = routing.NewRouteRegister()
|
||||||
|
err := gLive.Init()
|
||||||
|
require.NoError(t, err)
|
||||||
|
return gLive
|
||||||
|
}
|
||||||
|
|
||||||
// This tests three main scenarios.
|
// This tests three main scenarios.
|
||||||
// If a user has access to execute an action on a dashboard:
|
// If a user has access to execute an action on a dashboard:
|
||||||
// 1. and the dashboard is in a folder which does not have an acl
|
// 1. and the dashboard is in a folder which does not have an acl
|
||||||
@ -263,7 +271,8 @@ func TestDashboardAPIEndpoint(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("Given a dashboard with a parent folder which has an ACL", func(t *testing.T) {
|
t.Run("Given a dashboard with a parent folder which has an ACL", func(t *testing.T) {
|
||||||
hs := &HTTPServer{
|
hs := &HTTPServer{
|
||||||
Cfg: setting.NewCfg(),
|
Cfg: setting.NewCfg(),
|
||||||
|
Live: newTestLive(t),
|
||||||
}
|
}
|
||||||
|
|
||||||
setUp := func() *testState {
|
setUp := func() *testState {
|
||||||
@ -1172,7 +1181,7 @@ func postDashboardScenario(t *testing.T, desc string, url string, routePattern s
|
|||||||
Bus: bus.GetBus(),
|
Bus: bus.GetBus(),
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
ProvisioningService: provisioning.NewProvisioningServiceMock(),
|
ProvisioningService: provisioning.NewProvisioningServiceMock(),
|
||||||
Live: &live.GrafanaLive{Cfg: setting.NewCfg()},
|
Live: newTestLive(t),
|
||||||
QuotaService: "a.QuotaService{
|
QuotaService: "a.QuotaService{
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
},
|
},
|
||||||
@ -1236,7 +1245,7 @@ func restoreDashboardVersionScenario(t *testing.T, desc string, url string, rout
|
|||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
Bus: bus.GetBus(),
|
Bus: bus.GetBus(),
|
||||||
ProvisioningService: provisioning.NewProvisioningServiceMock(),
|
ProvisioningService: provisioning.NewProvisioningServiceMock(),
|
||||||
Live: &live.GrafanaLive{Cfg: cfg},
|
Live: newTestLive(t),
|
||||||
QuotaService: "a.QuotaService{Cfg: cfg},
|
QuotaService: "a.QuotaService{Cfg: cfg},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ func (g *GrafanaLive) getStreamPlugin(pluginID string) (backend.StreamHandler, e
|
|||||||
// AddMigration defines database migrations.
|
// AddMigration defines database migrations.
|
||||||
// This is an implementation of registry.DatabaseMigrator.
|
// This is an implementation of registry.DatabaseMigrator.
|
||||||
func (g *GrafanaLive) AddMigration(mg *migrator.Migrator) {
|
func (g *GrafanaLive) AddMigration(mg *migrator.Migrator) {
|
||||||
if !g.IsEnabled() {
|
if g == nil || g.Cfg == nil || !g.Cfg.IsLiveConfigEnabled() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
database.AddLiveChannelMigrations(mg)
|
database.AddLiveChannelMigrations(mg)
|
||||||
@ -136,11 +136,6 @@ var clientConcurrency = 8
|
|||||||
func (g *GrafanaLive) Init() error {
|
func (g *GrafanaLive) Init() error {
|
||||||
logger.Debug("GrafanaLive initialization")
|
logger.Debug("GrafanaLive initialization")
|
||||||
|
|
||||||
if !g.IsEnabled() {
|
|
||||||
logger.Debug("GrafanaLive feature not enabled, skipping initialization")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// We use default config here as starting point. Default config contains
|
// We use default config here as starting point. Default config contains
|
||||||
// reasonable values for available options.
|
// reasonable values for available options.
|
||||||
cfg := centrifuge.DefaultConfig
|
cfg := centrifuge.DefaultConfig
|
||||||
@ -530,14 +525,6 @@ func (g *GrafanaLive) ClientCount(channel string) (int, error) {
|
|||||||
return len(p.Presence), nil
|
return len(p.Presence), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEnabled returns true if the Grafana Live feature is enabled.
|
|
||||||
func (g *GrafanaLive) IsEnabled() bool {
|
|
||||||
if g == nil || g.Cfg == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return g.Cfg.IsLiveEnabled()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GrafanaLive) HandleHTTPPublish(ctx *models.ReqContext, cmd dtos.LivePublishCmd) response.Response {
|
func (g *GrafanaLive) HandleHTTPPublish(ctx *models.ReqContext, cmd dtos.LivePublishCmd) response.Response {
|
||||||
addr := live.ParseChannel(cmd.Channel)
|
addr := live.ParseChannel(cmd.Channel)
|
||||||
if !addr.IsValid() {
|
if !addr.IsValid() {
|
||||||
|
@ -34,30 +34,16 @@ type Gateway struct {
|
|||||||
func (g *Gateway) Init() error {
|
func (g *Gateway) Init() error {
|
||||||
logger.Info("Telemetry Gateway initialization")
|
logger.Info("Telemetry Gateway initialization")
|
||||||
|
|
||||||
if !g.IsEnabled() {
|
|
||||||
logger.Debug("Telemetry Gateway not enabled, skipping initialization")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
g.converter = convert.NewConverter()
|
g.converter = convert.NewConverter()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run Gateway.
|
// Run Gateway.
|
||||||
func (g *Gateway) Run(ctx context.Context) error {
|
func (g *Gateway) Run(ctx context.Context) error {
|
||||||
if !g.IsEnabled() {
|
|
||||||
logger.Debug("GrafanaLive feature not enabled, skipping initialization of Telemetry Gateway")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsEnabled returns true if the Grafana Live feature is enabled.
|
|
||||||
func (g *Gateway) IsEnabled() bool {
|
|
||||||
return g.Cfg.IsLiveEnabled() // turn on when Live on for now.
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *Gateway) Handle(ctx *models.ReqContext) {
|
func (g *Gateway) Handle(ctx *models.ReqContext) {
|
||||||
streamID := ctx.Params(":streamId")
|
streamID := ctx.Params(":streamId")
|
||||||
|
|
||||||
|
@ -374,9 +374,9 @@ type Cfg struct {
|
|||||||
ImageUploadProvider string
|
ImageUploadProvider string
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsLiveEnabled returns if grafana live should be enabled
|
// IsLiveConfigEnabled returns true if live should be able to save configs to SQL tables
|
||||||
func (cfg Cfg) IsLiveEnabled() bool {
|
func (cfg Cfg) IsLiveConfigEnabled() bool {
|
||||||
return cfg.FeatureToggles["live"]
|
return cfg.FeatureToggles["live-config"]
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsNgAlertEnabled returns whether the standalone alerts feature is enabled.
|
// IsNgAlertEnabled returns whether the standalone alerts feature is enabled.
|
||||||
|
@ -54,7 +54,7 @@ export class CentrifugeSrv implements GrafanaLiveSrv {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
// build live url replacing scheme in appUrl.
|
// build live url replacing scheme in appUrl.
|
||||||
const liveUrl = `${config.appUrl}live/ws`.replace(/^(http)(s)?:\/\//, 'ws$2://');
|
const liveUrl = `${config.appUrl.replace('http', 'ws')}live/ws`;
|
||||||
this.centrifuge = new Centrifuge(liveUrl, {
|
this.centrifuge = new Centrifuge(liveUrl, {
|
||||||
debug: true,
|
debug: true,
|
||||||
});
|
});
|
||||||
|
@ -65,7 +65,6 @@ import { CloudWatchLanguageProvider } from './language_provider';
|
|||||||
import { VariableWithMultiSupport } from 'app/features/variables/types';
|
import { VariableWithMultiSupport } from 'app/features/variables/types';
|
||||||
import { AwsUrl, encodeUrl } from './aws_url';
|
import { AwsUrl, encodeUrl } from './aws_url';
|
||||||
import { increasingInterval } from './utils/rxjs/increasingInterval';
|
import { increasingInterval } from './utils/rxjs/increasingInterval';
|
||||||
import config from 'app/core/config';
|
|
||||||
|
|
||||||
const DS_QUERY_ENDPOINT = '/api/ds/query';
|
const DS_QUERY_ENDPOINT = '/api/ds/query';
|
||||||
|
|
||||||
@ -128,11 +127,8 @@ export class CloudWatchDatasource extends DataSourceApi<CloudWatchQuery, CloudWa
|
|||||||
|
|
||||||
const dataQueryResponses: Array<Observable<DataQueryResponse>> = [];
|
const dataQueryResponses: Array<Observable<DataQueryResponse>> = [];
|
||||||
if (logQueries.length > 0) {
|
if (logQueries.length > 0) {
|
||||||
if (config.featureToggles.live) {
|
dataQueryResponses.push(this.handleLiveLogQueries(logQueries, options));
|
||||||
dataQueryResponses.push(this.handleLiveLogQueries(logQueries, options));
|
// dataQueryResponses.push(this.handleLogQueries(logQueries, options));
|
||||||
} else {
|
|
||||||
dataQueryResponses.push(this.handleLogQueries(logQueries, options));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metricsQueries.length > 0) {
|
if (metricsQueries.length > 0) {
|
||||||
|
@ -57,10 +57,7 @@ export class GrafanaCtrl {
|
|||||||
|
|
||||||
setLocationSrv(locationService);
|
setLocationSrv(locationService);
|
||||||
|
|
||||||
// Initialize websocket event streaming
|
initGrafanaLive();
|
||||||
if (config.featureToggles.live) {
|
|
||||||
initGrafanaLive();
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.init = () => {
|
$scope.init = () => {
|
||||||
$scope.contextSrv = contextSrv;
|
$scope.contextSrv = contextSrv;
|
||||||
|
Loading…
Reference in New Issue
Block a user