diff --git a/docs/main/administration-guide/configure/environment-configuration-settings.mdx b/docs/main/administration-guide/configure/environment-configuration-settings.mdx index 43ab0a2c197..2c2f8a38635 100644 --- a/docs/main/administration-guide/configure/environment-configuration-settings.mdx +++ b/docs/main/administration-guide/configure/environment-configuration-settings.mdx @@ -3426,7 +3426,7 @@ See the [performance monitoring](/administration-guide/scale/deploy-prometheus-g - `MetricsSettings.Enable` must be set to `true` -- The `NotificationMonitoring` feature flag must be set to `true` +- `MetricsSettings.EnableNotificationMetrics` must be set to `true` diff --git a/docs/main/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring.mdx b/docs/main/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring.mdx index abc5ba57ba9..879ee06f24d 100644 --- a/docs/main/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring.mdx +++ b/docs/main/administration-guide/scale/deploy-prometheus-grafana-for-performance-monitoring.mdx @@ -117,7 +117,7 @@ See [this Grafana guide](https://grafana.com/docs/grafana/v7.5/dashboards/export - [Mattermost Performance Monitoring v2](https://grafana.com/grafana/dashboards/15582-mattermost-performance-monitoring-v2/), which contains detailed charts for performance monitoring including application, cluster, job server, and system metrics. -- [Mattermost Notification Health Monitoring](https://grafana.com/grafana/dashboards/21305-mattermost-notification-health/), which can be used to track different types of notifications sent from Mattermost. Accessing and enabling Mattermost Notification Health Monitoring requires the feature flag `NotificationMonitoring` to be set to `true`. System admins can [disable notification monitoring data collection](/administration-guide/configure/site-configuration-settings#enable-notification-monitoring) through the System Console. +- [Mattermost Notification Health Monitoring](https://grafana.com/grafana/dashboards/21305-mattermost-notification-health/), which can be used to track different types of notifications sent from Mattermost. System admins can [disable notification monitoring data collection](/administration-guide/configure/site-configuration-settings#enable-notification-monitoring) through the System Console. - [Mattermost Web App Performance Metrics](https://grafana.com/grafana/dashboards/21460-web-app-metrics/), which contains detailed metrics for client-side performance, including web vitals and Mattermost-specifc metrics. - [Mattermost Desktop App Performance Metrics](https://grafana.com/grafana/dashboards/22736-desktop-app-metrics/), which contains detailed metrics for client-side desktop performance, including CPU and memory usage metrics. - [Mattermost Mobile App Performance Metrics](https://grafana.com/grafana/dashboards/21695-mobile-performance-metrics/), which contains detailed metrics for client-side mobile performance, including web vitals and Mattermost-specifc metrics. diff --git a/docs/main/administration-guide/scale/push-notification-health-targets.mdx b/docs/main/administration-guide/scale/push-notification-health-targets.mdx index ba65de7b85b..575f1f7b8d4 100644 --- a/docs/main/administration-guide/scale/push-notification-health-targets.mdx +++ b/docs/main/administration-guide/scale/push-notification-health-targets.mdx @@ -7,7 +7,7 @@ When using the [Mattermost Notification Health](https://grafana.com/grafana/dash -- Accessing and enabling Mattermost Notification Health Monitoring requires `MetricsSettings.Enable` set to `true`, and the feature flag `NotificationMonitoring` set to `true`. +- Accessing and enabling Mattermost Notification Health Monitoring requires `MetricsSettings.Enable` set to `true`. - `MetricsSettings.EnableNotificationMetrics` must be enabled in the [Performance Monitoring](/administration-guide/configure/environment-configuration-settings#enable-notification-monitoring) configuration. - System admins can [disable notification monitoring data collection](/administration-guide/configure/site-configuration-settings#enable-notification-monitoring) through the System Console. diff --git a/e2e-tests/playwright/lib/src/server/default_config.ts b/e2e-tests/playwright/lib/src/server/default_config.ts index f32e5333475..7e9f40a4f8d 100644 --- a/e2e-tests/playwright/lib/src/server/default_config.ts +++ b/e2e-tests/playwright/lib/src/server/default_config.ts @@ -802,7 +802,6 @@ const defaultServerConfig: AdminConfig = { StreamlinedMarketplace: true, CloudDedicatedExportUI: false, WebSocketEventScope: true, - NotificationMonitoring: true, ExperimentalAuditSettingsSystemConsoleUI: true, CustomProfileAttributes: true, AttributeBasedAccessControl: true, diff --git a/server/channels/app/metrics_test.go b/server/channels/app/metrics_test.go index 9879b7347d9..9c3747f19fd 100644 --- a/server/channels/app/metrics_test.go +++ b/server/channels/app/metrics_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/mattermost/mattermost/server/public/model" + "github.com/mattermost/mattermost/server/v8/channels/app/platform" "github.com/mattermost/mattermost/server/v8/enterprise/metrics" "github.com/prometheus/client_golang/prometheus" prometheusModels "github.com/prometheus/client_model/go" @@ -100,3 +101,109 @@ func TestMobileMetrics(t *testing.T) { } } } + +func TestCountNotificationMetrics(t *testing.T) { + mainHelper.Parallel(t) + th := SetupEnterprise(t, StartMetrics) + + configureMetrics(th) + mi := th.App.Metrics() + + miImpl, ok := mi.(*metrics.MetricsInterfaceImpl) + require.True(t, ok, fmt.Sprintf("App.Metrics is not *MetricsInterfaceImpl, but %T", mi)) + + counterValue := func() float64 { + counter, err := miImpl.NotificationTotalCounters.GetMetricWith(prometheus.Labels{ + "type": string(model.NotificationTypePush), + "platform": "ios", + }) + require.NoError(t, err) + m := &prometheusModels.Metric{} + require.NoError(t, counter.Write(m)) + return m.Counter.GetValue() + } + + t.Run("counts when notification metrics are enabled", func(t *testing.T) { + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MetricsSettings.EnableNotificationMetrics = true + }) + + before := counterValue() + th.App.CountNotification(model.NotificationTypePush, "ios") + require.Equal(t, before+1, counterValue()) + }) + + t.Run("does not count when notification metrics are disabled", func(t *testing.T) { + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MetricsSettings.EnableNotificationMetrics = false + }) + + before := counterValue() + th.App.CountNotification(model.NotificationTypePush, "ios") + require.Equal(t, before, counterValue()) + }) +} + +func TestWebsocketNotificationCounter(t *testing.T) { + mainHelper.Parallel(t) + th := SetupEnterprise(t, StartMetrics) + + configureMetrics(th) + mi := th.App.Metrics() + + miImpl, ok := mi.(*metrics.MetricsInterfaceImpl) + require.True(t, ok, fmt.Sprintf("App.Metrics is not *MetricsInterfaceImpl, but %T", mi)) + + counterValue := func() float64 { + counter, err := miImpl.NotificationTotalCounters.GetMetricWith(prometheus.Labels{ + "type": string(model.NotificationTypeWebsocket), + "platform": model.NotificationNoPlatform, + }) + require.NoError(t, err) + m := &prometheusModels.Metric{} + require.NoError(t, counter.Write(m)) + return m.Counter.GetValue() + } + + hook := &postedAckBroadcastHook{} + userID := model.NewId() + webConn := &platform.WebConn{ + UserId: userID, + Platform: th.Server.Platform(), + PostedAck: true, + } + webConn.Active.Store(true) + webConn.SetSession(&model.Session{}) + + // Process an acked broadcast that reaches incrementWebsocketCounter. + ackPostedBroadcast := func() { + msg := platform.MakeHookedWebSocketEvent(model.NewWebSocketEvent(model.WebsocketEventPosted, "", "", "", nil, "")) + err := hook.Process(msg, webConn, map[string]any{ + "posted_user_id": model.NewId(), + "channel_type": model.ChannelTypeOpen, + "users": []string{userID}, + }) + require.NoError(t, err) + require.True(t, msg.Event().GetData()["should_ack"].(bool)) + } + + t.Run("counts when notification metrics are enabled", func(t *testing.T) { + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MetricsSettings.EnableNotificationMetrics = true + }) + + before := counterValue() + ackPostedBroadcast() + require.Equal(t, before+1, counterValue()) + }) + + t.Run("does not count when notification metrics are disabled", func(t *testing.T) { + th.App.UpdateConfig(func(cfg *model.Config) { + *cfg.MetricsSettings.EnableNotificationMetrics = false + }) + + before := counterValue() + ackPostedBroadcast() + require.Equal(t, before, counterValue()) + }) +} diff --git a/server/channels/app/notification.go b/server/channels/app/notification.go index 232682841c0..00f4a97068d 100644 --- a/server/channels/app/notification.go +++ b/server/channels/app/notification.go @@ -1812,7 +1812,7 @@ func (a *App) notificationMetricsDisabled() bool { return true } - if a.Config().FeatureFlags.NotificationMonitoring && *a.Config().MetricsSettings.EnableNotificationMetrics { + if *a.Config().MetricsSettings.EnableNotificationMetrics { return false } diff --git a/server/channels/app/web_broadcast_hooks.go b/server/channels/app/web_broadcast_hooks.go index 32a9c647b77..587089776ef 100644 --- a/server/channels/app/web_broadcast_hooks.go +++ b/server/channels/app/web_broadcast_hooks.go @@ -539,7 +539,7 @@ func incrementWebsocketCounter(wc *platform.WebConn) { return } - if !(wc.Platform.Config().FeatureFlags.NotificationMonitoring && *wc.Platform.Config().MetricsSettings.EnableNotificationMetrics) { + if !*wc.Platform.Config().MetricsSettings.EnableNotificationMetrics { return } diff --git a/server/config/client.go b/server/config/client.go index 128b0df01e2..e5268502bbc 100644 --- a/server/config/client.go +++ b/server/config/client.go @@ -201,7 +201,7 @@ func GenerateClientConfig(c *model.Config, telemetryID string, license *model.Li if *license.Features.Cluster { props["EnableMetrics"] = strconv.FormatBool(*c.MetricsSettings.Enable) props["EnableClientMetrics"] = strconv.FormatBool(*c.MetricsSettings.Enable && *c.MetricsSettings.EnableClientMetrics) - props["EnableNotificationMetrics"] = strconv.FormatBool(c.FeatureFlags.NotificationMonitoring && *c.MetricsSettings.EnableNotificationMetrics) + props["EnableNotificationMetrics"] = strconv.FormatBool(*c.MetricsSettings.EnableNotificationMetrics) } if *license.Features.Announcement { diff --git a/server/config/client_test.go b/server/config/client_test.go index 53a9511fd86..eb4e64936b1 100644 --- a/server/config/client_test.go +++ b/server/config/client_test.go @@ -728,6 +728,46 @@ func TestGetClientConfig(t *testing.T) { map[string]string{}, []string{"MobileEphemeralModeEnabled", "MobileEphemeralModeDisconnectionTimeoutSeconds", "MobileEphemeralModeOfflinePersistenceTimerHours", "MobileEphemeralModeAutoCacheCleanupDays"}, }, + { + "notification metrics enabled follows the metrics setting", + &model.Config{ + MetricsSettings: model.MetricsSettings{ + Enable: new(true), + EnableNotificationMetrics: new(true), + }, + }, + "", + &model.License{ + Features: &model.Features{ + Cluster: new(true), + }, + }, + map[string]string{ + "EnableMetrics": "true", + "EnableNotificationMetrics": "true", + }, + nil, + }, + { + "notification metrics disabled follows the metrics setting", + &model.Config{ + MetricsSettings: model.MetricsSettings{ + Enable: new(true), + EnableNotificationMetrics: new(false), + }, + }, + "", + &model.License{ + Features: &model.Features{ + Cluster: new(true), + }, + }, + map[string]string{ + "EnableMetrics": "true", + "EnableNotificationMetrics": "false", + }, + nil, + }, } for _, testCase := range testCases { diff --git a/server/public/model/feature_flags.go b/server/public/model/feature_flags.go index c2daf150142..8e4f79192de 100644 --- a/server/public/model/feature_flags.go +++ b/server/public/model/feature_flags.go @@ -42,8 +42,6 @@ type FeatureFlags struct { WebSocketEventScope bool - NotificationMonitoring bool - ExperimentalAuditSettingsSystemConsoleUI bool CustomProfileAttributes bool @@ -161,7 +159,6 @@ func (f *FeatureFlags) SetDefaults() { f.StreamlinedMarketplace = true f.CloudDedicatedExportUI = false f.WebSocketEventScope = true - f.NotificationMonitoring = true f.ExperimentalAuditSettingsSystemConsoleUI = true f.CustomProfileAttributes = true f.AttributeBasedAccessControl = true diff --git a/webapp/channels/src/components/admin_console/admin_definition.tsx b/webapp/channels/src/components/admin_console/admin_definition.tsx index c01756a5eed..8788c2f376d 100644 --- a/webapp/channels/src/components/admin_console/admin_definition.tsx +++ b/webapp/channels/src/components/admin_console/admin_definition.tsx @@ -3459,7 +3459,6 @@ const AdminDefinition: AdminDefinitionType = { isDisabled: it.any( it.configIsFalse('MetricsSettings', 'Enable'), ), - isHidden: it.configIsFalse('FeatureFlags', 'NotificationMonitoring'), }, ], },