github.com/vnforks/kid@v5.11.1+incompatible/app/diagnostics.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"path/filepath"
     8  	"runtime"
     9  	"strings"
    10  
    11  	"github.com/mattermost/mattermost-server/mlog"
    12  	"github.com/mattermost/mattermost-server/model"
    13  	analytics "github.com/segmentio/analytics-go"
    14  )
    15  
    16  const (
    17  	SEGMENT_KEY = "placeholder_segment_key"
    18  
    19  	TRACK_CONFIG_SERVICE            = "config_service"
    20  	TRACK_CONFIG_TEAM               = "config_team"
    21  	TRACK_CONFIG_CLIENT_REQ         = "config_client_requirements"
    22  	TRACK_CONFIG_SQL                = "config_sql"
    23  	TRACK_CONFIG_LOG                = "config_log"
    24  	TRACK_CONFIG_FILE               = "config_file"
    25  	TRACK_CONFIG_RATE               = "config_rate"
    26  	TRACK_CONFIG_EMAIL              = "config_email"
    27  	TRACK_CONFIG_PRIVACY            = "config_privacy"
    28  	TRACK_CONFIG_THEME              = "config_theme"
    29  	TRACK_CONFIG_OAUTH              = "config_oauth"
    30  	TRACK_CONFIG_LDAP               = "config_ldap"
    31  	TRACK_CONFIG_COMPLIANCE         = "config_compliance"
    32  	TRACK_CONFIG_LOCALIZATION       = "config_localization"
    33  	TRACK_CONFIG_SAML               = "config_saml"
    34  	TRACK_CONFIG_PASSWORD           = "config_password"
    35  	TRACK_CONFIG_CLUSTER            = "config_cluster"
    36  	TRACK_CONFIG_METRICS            = "config_metrics"
    37  	TRACK_CONFIG_SUPPORT            = "config_support"
    38  	TRACK_CONFIG_NATIVEAPP          = "config_nativeapp"
    39  	TRACK_CONFIG_EXPERIMENTAL       = "config_experimental"
    40  	TRACK_CONFIG_ANALYTICS          = "config_analytics"
    41  	TRACK_CONFIG_ANNOUNCEMENT       = "config_announcement"
    42  	TRACK_CONFIG_ELASTICSEARCH      = "config_elasticsearch"
    43  	TRACK_CONFIG_PLUGIN             = "config_plugin"
    44  	TRACK_CONFIG_DATA_RETENTION     = "config_data_retention"
    45  	TRACK_CONFIG_MESSAGE_EXPORT     = "config_message_export"
    46  	TRACK_CONFIG_DISPLAY            = "config_display"
    47  	TRACK_CONFIG_IMAGE_PROXY        = "config_image_proxy"
    48  	TRACK_PERMISSIONS_GENERAL       = "permissions_general"
    49  	TRACK_PERMISSIONS_SYSTEM_SCHEME = "permissions_system_scheme"
    50  	TRACK_PERMISSIONS_TEAM_SCHEMES  = "permissions_team_schemes"
    51  
    52  	TRACK_ACTIVITY = "activity"
    53  	TRACK_LICENSE  = "license"
    54  	TRACK_SERVER   = "server"
    55  	TRACK_PLUGINS  = "plugins"
    56  )
    57  
    58  var client *analytics.Client
    59  
    60  func (a *App) SendDailyDiagnostics() {
    61  	a.sendDailyDiagnostics(false)
    62  }
    63  
    64  func (a *App) sendDailyDiagnostics(override bool) {
    65  	if *a.Config().LogSettings.EnableDiagnostics && a.IsLeader() && (!strings.Contains(SEGMENT_KEY, "placeholder") || override) {
    66  		a.initDiagnostics("")
    67  		a.trackActivity()
    68  		a.trackConfig()
    69  		a.trackLicense()
    70  		a.trackPlugins()
    71  		a.trackServer()
    72  		a.trackPermissions()
    73  	}
    74  }
    75  
    76  func (a *App) initDiagnostics(endpoint string) {
    77  	if client == nil {
    78  		client = analytics.New(SEGMENT_KEY)
    79  		client.Logger = a.Log.StdLog(mlog.String("source", "segment"))
    80  		// For testing
    81  		if endpoint != "" {
    82  			client.Endpoint = endpoint
    83  			client.Verbose = true
    84  			client.Size = 1
    85  		}
    86  		client.Identify(&analytics.Identify{
    87  			UserId: a.DiagnosticId(),
    88  		})
    89  	}
    90  }
    91  
    92  func (a *App) SendDiagnostic(event string, properties map[string]interface{}) {
    93  	client.Track(&analytics.Track{
    94  		Event:      event,
    95  		UserId:     a.DiagnosticId(),
    96  		Properties: properties,
    97  	})
    98  }
    99  
   100  func isDefault(setting interface{}, defaultValue interface{}) bool {
   101  	return setting == defaultValue
   102  }
   103  
   104  func pluginSetting(pluginSettings *model.PluginSettings, plugin, key string, defaultValue interface{}) interface{} {
   105  	settings, ok := pluginSettings.Plugins[plugin]
   106  	if !ok {
   107  		return defaultValue
   108  	}
   109  	if value, ok := settings[key]; ok {
   110  		return value
   111  	}
   112  	return defaultValue
   113  }
   114  
   115  func pluginActivated(pluginStates map[string]*model.PluginState, pluginId string) bool {
   116  	state, ok := pluginStates[pluginId]
   117  	if !ok {
   118  		return false
   119  	}
   120  	return state.Enable
   121  }
   122  
   123  func (a *App) trackActivity() {
   124  	var userCount int64
   125  	var botAccountsCount int64
   126  	var activeUsersDailyCount int64
   127  	var activeUsersMonthlyCount int64
   128  	var inactiveUserCount int64
   129  	var teamCount int64
   130  	var publicChannelCount int64
   131  	var privateChannelCount int64
   132  	var directChannelCount int64
   133  	var deletedPublicChannelCount int64
   134  	var deletedPrivateChannelCount int64
   135  	var postsCount int64
   136  	var slashCommandsCount int64
   137  	var incomingWebhooksCount int64
   138  	var outgoingWebhooksCount int64
   139  
   140  	dailyActiveChan := a.Srv.Store.User().AnalyticsActiveCount(DAY_MILLISECONDS)
   141  	monthlyActiveChan := a.Srv.Store.User().AnalyticsActiveCount(MONTH_MILLISECONDS)
   142  
   143  	if r := <-dailyActiveChan; r.Err == nil {
   144  		activeUsersDailyCount = r.Data.(int64)
   145  	}
   146  
   147  	if r := <-monthlyActiveChan; r.Err == nil {
   148  		activeUsersMonthlyCount = r.Data.(int64)
   149  	}
   150  
   151  	if ucr := <-a.Srv.Store.User().Count(model.UserCountOptions{
   152  		IncludeDeleted: true,
   153  	}); ucr.Err == nil {
   154  		userCount = ucr.Data.(int64)
   155  	}
   156  
   157  	if bc := <-a.Srv.Store.User().Count(model.UserCountOptions{
   158  		IncludeBotAccounts:  true,
   159  		ExcludeRegularUsers: true,
   160  	}); bc.Err == nil {
   161  		botAccountsCount = bc.Data.(int64)
   162  	}
   163  
   164  	if iucr := <-a.Srv.Store.User().AnalyticsGetInactiveUsersCount(); iucr.Err == nil {
   165  		inactiveUserCount = iucr.Data.(int64)
   166  	}
   167  
   168  	if tcr := <-a.Srv.Store.Team().AnalyticsTeamCount(); tcr.Err == nil {
   169  		teamCount = tcr.Data.(int64)
   170  	}
   171  
   172  	if ucc := <-a.Srv.Store.Channel().AnalyticsTypeCount("", "O"); ucc.Err == nil {
   173  		publicChannelCount = ucc.Data.(int64)
   174  	}
   175  
   176  	if pcc := <-a.Srv.Store.Channel().AnalyticsTypeCount("", "P"); pcc.Err == nil {
   177  		privateChannelCount = pcc.Data.(int64)
   178  	}
   179  
   180  	if dcc := <-a.Srv.Store.Channel().AnalyticsTypeCount("", "D"); dcc.Err == nil {
   181  		directChannelCount = dcc.Data.(int64)
   182  	}
   183  
   184  	if duccr := <-a.Srv.Store.Channel().AnalyticsDeletedTypeCount("", "O"); duccr.Err == nil {
   185  		deletedPublicChannelCount = duccr.Data.(int64)
   186  	}
   187  
   188  	if dpccr := <-a.Srv.Store.Channel().AnalyticsDeletedTypeCount("", "P"); dpccr.Err == nil {
   189  		deletedPrivateChannelCount = dpccr.Data.(int64)
   190  	}
   191  
   192  	if pcr := <-a.Srv.Store.Post().AnalyticsPostCount("", false, false); pcr.Err == nil {
   193  		postsCount = pcr.Data.(int64)
   194  	}
   195  
   196  	if scc := <-a.Srv.Store.Command().AnalyticsCommandCount(""); scc.Err == nil {
   197  		slashCommandsCount = scc.Data.(int64)
   198  	}
   199  
   200  	if iwc := <-a.Srv.Store.Webhook().AnalyticsIncomingCount(""); iwc.Err == nil {
   201  		incomingWebhooksCount = iwc.Data.(int64)
   202  	}
   203  
   204  	if owc := <-a.Srv.Store.Webhook().AnalyticsOutgoingCount(""); owc.Err == nil {
   205  		outgoingWebhooksCount = owc.Data.(int64)
   206  	}
   207  
   208  	a.SendDiagnostic(TRACK_ACTIVITY, map[string]interface{}{
   209  		"registered_users":             userCount,
   210  		"bot_accounts":                 botAccountsCount,
   211  		"active_users_daily":           activeUsersDailyCount,
   212  		"active_users_monthly":         activeUsersMonthlyCount,
   213  		"registered_deactivated_users": inactiveUserCount,
   214  		"teams":                        teamCount,
   215  		"public_channels":              publicChannelCount,
   216  		"private_channels":             privateChannelCount,
   217  		"direct_message_channels":      directChannelCount,
   218  		"public_channels_deleted":      deletedPublicChannelCount,
   219  		"private_channels_deleted":     deletedPrivateChannelCount,
   220  		"posts":                        postsCount,
   221  		"slash_commands":               slashCommandsCount,
   222  		"incoming_webhooks":            incomingWebhooksCount,
   223  		"outgoing_webhooks":            outgoingWebhooksCount,
   224  	})
   225  }
   226  
   227  func (a *App) trackConfig() {
   228  	cfg := a.Config()
   229  	a.SendDiagnostic(TRACK_CONFIG_SERVICE, map[string]interface{}{
   230  		"web_server_mode":                                         *cfg.ServiceSettings.WebserverMode,
   231  		"enable_security_fix_alert":                               *cfg.ServiceSettings.EnableSecurityFixAlert,
   232  		"enable_insecure_outgoing_connections":                    *cfg.ServiceSettings.EnableInsecureOutgoingConnections,
   233  		"enable_incoming_webhooks":                                cfg.ServiceSettings.EnableIncomingWebhooks,
   234  		"enable_outgoing_webhooks":                                cfg.ServiceSettings.EnableOutgoingWebhooks,
   235  		"enable_commands":                                         *cfg.ServiceSettings.EnableCommands,
   236  		"enable_only_admin_integrations":                          *cfg.ServiceSettings.DEPRECATED_DO_NOT_USE_EnableOnlyAdminIntegrations,
   237  		"enable_post_username_override":                           cfg.ServiceSettings.EnablePostUsernameOverride,
   238  		"enable_post_icon_override":                               cfg.ServiceSettings.EnablePostIconOverride,
   239  		"enable_user_access_tokens":                               *cfg.ServiceSettings.EnableUserAccessTokens,
   240  		"enable_custom_emoji":                                     *cfg.ServiceSettings.EnableCustomEmoji,
   241  		"enable_emoji_picker":                                     *cfg.ServiceSettings.EnableEmojiPicker,
   242  		"enable_gif_picker":                                       *cfg.ServiceSettings.EnableGifPicker,
   243  		"gfycat_api_key":                                          isDefault(*cfg.ServiceSettings.GfycatApiKey, model.SERVICE_SETTINGS_DEFAULT_GFYCAT_API_KEY),
   244  		"gfycat_api_secret":                                       isDefault(*cfg.ServiceSettings.GfycatApiSecret, model.SERVICE_SETTINGS_DEFAULT_GFYCAT_API_SECRET),
   245  		"experimental_enable_authentication_transfer":             *cfg.ServiceSettings.ExperimentalEnableAuthenticationTransfer,
   246  		"restrict_custom_emoji_creation":                          *cfg.ServiceSettings.DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation,
   247  		"enable_testing":                                          cfg.ServiceSettings.EnableTesting,
   248  		"enable_developer":                                        *cfg.ServiceSettings.EnableDeveloper,
   249  		"enable_multifactor_authentication":                       *cfg.ServiceSettings.EnableMultifactorAuthentication,
   250  		"enforce_multifactor_authentication":                      *cfg.ServiceSettings.EnforceMultifactorAuthentication,
   251  		"enable_oauth_service_provider":                           cfg.ServiceSettings.EnableOAuthServiceProvider,
   252  		"connection_security":                                     *cfg.ServiceSettings.ConnectionSecurity,
   253  		"tls_strict_transport":                                    *cfg.ServiceSettings.TLSStrictTransport,
   254  		"uses_letsencrypt":                                        *cfg.ServiceSettings.UseLetsEncrypt,
   255  		"forward_80_to_443":                                       *cfg.ServiceSettings.Forward80To443,
   256  		"maximum_login_attempts":                                  *cfg.ServiceSettings.MaximumLoginAttempts,
   257  		"session_length_web_in_days":                              *cfg.ServiceSettings.SessionLengthWebInDays,
   258  		"session_length_mobile_in_days":                           *cfg.ServiceSettings.SessionLengthMobileInDays,
   259  		"session_length_sso_in_days":                              *cfg.ServiceSettings.SessionLengthSSOInDays,
   260  		"session_cache_in_minutes":                                *cfg.ServiceSettings.SessionCacheInMinutes,
   261  		"session_idle_timeout_in_minutes":                         *cfg.ServiceSettings.SessionIdleTimeoutInMinutes,
   262  		"isdefault_site_url":                                      isDefault(*cfg.ServiceSettings.SiteURL, model.SERVICE_SETTINGS_DEFAULT_SITE_URL),
   263  		"isdefault_tls_cert_file":                                 isDefault(*cfg.ServiceSettings.TLSCertFile, model.SERVICE_SETTINGS_DEFAULT_TLS_CERT_FILE),
   264  		"isdefault_tls_key_file":                                  isDefault(*cfg.ServiceSettings.TLSKeyFile, model.SERVICE_SETTINGS_DEFAULT_TLS_KEY_FILE),
   265  		"isdefault_read_timeout":                                  isDefault(*cfg.ServiceSettings.ReadTimeout, model.SERVICE_SETTINGS_DEFAULT_READ_TIMEOUT),
   266  		"isdefault_write_timeout":                                 isDefault(*cfg.ServiceSettings.WriteTimeout, model.SERVICE_SETTINGS_DEFAULT_WRITE_TIMEOUT),
   267  		"isdefault_google_developer_key":                          isDefault(cfg.ServiceSettings.GoogleDeveloperKey, ""),
   268  		"isdefault_allow_cors_from":                               isDefault(*cfg.ServiceSettings.AllowCorsFrom, model.SERVICE_SETTINGS_DEFAULT_ALLOW_CORS_FROM),
   269  		"isdefault_cors_exposed_headers":                          isDefault(cfg.ServiceSettings.CorsExposedHeaders, ""),
   270  		"cors_allow_credentials":                                  *cfg.ServiceSettings.CorsAllowCredentials,
   271  		"cors_debug":                                              *cfg.ServiceSettings.CorsDebug,
   272  		"isdefault_allowed_untrusted_internal_connections":        isDefault(*cfg.ServiceSettings.AllowedUntrustedInternalConnections, ""),
   273  		"restrict_post_delete":                                    *cfg.ServiceSettings.DEPRECATED_DO_NOT_USE_RestrictPostDelete,
   274  		"allow_edit_post":                                         *cfg.ServiceSettings.DEPRECATED_DO_NOT_USE_AllowEditPost,
   275  		"post_edit_time_limit":                                    *cfg.ServiceSettings.PostEditTimeLimit,
   276  		"enable_user_typing_messages":                             *cfg.ServiceSettings.EnableUserTypingMessages,
   277  		"enable_channel_viewed_messages":                          *cfg.ServiceSettings.EnableChannelViewedMessages,
   278  		"time_between_user_typing_updates_milliseconds":           *cfg.ServiceSettings.TimeBetweenUserTypingUpdatesMilliseconds,
   279  		"cluster_log_timeout_milliseconds":                        *cfg.ServiceSettings.ClusterLogTimeoutMilliseconds,
   280  		"enable_post_search":                                      *cfg.ServiceSettings.EnablePostSearch,
   281  		"minimum_hashtag_length":                                  *cfg.ServiceSettings.MinimumHashtagLength,
   282  		"enable_user_statuses":                                    *cfg.ServiceSettings.EnableUserStatuses,
   283  		"close_unused_direct_messages":                            *cfg.ServiceSettings.CloseUnusedDirectMessages,
   284  		"enable_preview_features":                                 *cfg.ServiceSettings.EnablePreviewFeatures,
   285  		"enable_tutorial":                                         *cfg.ServiceSettings.EnableTutorial,
   286  		"experimental_enable_default_channel_leave_join_messages": *cfg.ServiceSettings.ExperimentalEnableDefaultChannelLeaveJoinMessages,
   287  		"experimental_group_unread_channels":                      *cfg.ServiceSettings.ExperimentalGroupUnreadChannels,
   288  		"websocket_url":                                           isDefault(*cfg.ServiceSettings.WebsocketURL, ""),
   289  		"allow_cookies_for_subdomains":                            *cfg.ServiceSettings.AllowCookiesForSubdomains,
   290  		"enable_api_team_deletion":                                *cfg.ServiceSettings.EnableAPITeamDeletion,
   291  		"experimental_enable_hardened_mode":                       *cfg.ServiceSettings.ExperimentalEnableHardenedMode,
   292  		"experimental_strict_csrf_enforcement":                    *cfg.ServiceSettings.ExperimentalStrictCSRFEnforcement,
   293  		"enable_email_invitations":                                *cfg.ServiceSettings.EnableEmailInvitations,
   294  		"experimental_channel_organization":                       *cfg.ServiceSettings.ExperimentalChannelOrganization,
   295  		"experimental_ldap_group_sync":                            *cfg.ServiceSettings.ExperimentalLdapGroupSync,
   296  		"disable_bots_when_owner_is_deactivated":                  *cfg.ServiceSettings.DisableBotsWhenOwnerIsDeactivated,
   297  	})
   298  
   299  	a.SendDiagnostic(TRACK_CONFIG_TEAM, map[string]interface{}{
   300  		"enable_user_creation":                      cfg.TeamSettings.EnableUserCreation,
   301  		"enable_team_creation":                      *cfg.TeamSettings.DEPRECATED_DO_NOT_USE_EnableTeamCreation,
   302  		"restrict_team_invite":                      *cfg.TeamSettings.DEPRECATED_DO_NOT_USE_RestrictTeamInvite,
   303  		"restrict_public_channel_creation":          *cfg.TeamSettings.DEPRECATED_DO_NOT_USE_RestrictPublicChannelCreation,
   304  		"restrict_private_channel_creation":         *cfg.TeamSettings.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelCreation,
   305  		"restrict_public_channel_management":        *cfg.TeamSettings.DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement,
   306  		"restrict_private_channel_management":       *cfg.TeamSettings.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement,
   307  		"restrict_public_channel_deletion":          *cfg.TeamSettings.DEPRECATED_DO_NOT_USE_RestrictPublicChannelDeletion,
   308  		"restrict_private_channel_deletion":         *cfg.TeamSettings.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelDeletion,
   309  		"enable_open_server":                        *cfg.TeamSettings.EnableOpenServer,
   310  		"enable_user_deactivation":                  *cfg.TeamSettings.EnableUserDeactivation,
   311  		"enable_custom_brand":                       *cfg.TeamSettings.EnableCustomBrand,
   312  		"restrict_direct_message":                   *cfg.TeamSettings.RestrictDirectMessage,
   313  		"max_notifications_per_channel":             *cfg.TeamSettings.MaxNotificationsPerChannel,
   314  		"enable_confirm_notifications_to_channel":   *cfg.TeamSettings.EnableConfirmNotificationsToChannel,
   315  		"max_users_per_team":                        *cfg.TeamSettings.MaxUsersPerTeam,
   316  		"max_channels_per_team":                     *cfg.TeamSettings.MaxChannelsPerTeam,
   317  		"teammate_name_display":                     *cfg.TeamSettings.TeammateNameDisplay,
   318  		"experimental_view_archived_channels":       *cfg.TeamSettings.ExperimentalViewArchivedChannels,
   319  		"isdefault_site_name":                       isDefault(cfg.TeamSettings.SiteName, "Mattermost"),
   320  		"isdefault_custom_brand_text":               isDefault(*cfg.TeamSettings.CustomBrandText, model.TEAM_SETTINGS_DEFAULT_CUSTOM_BRAND_TEXT),
   321  		"isdefault_custom_description_text":         isDefault(*cfg.TeamSettings.CustomDescriptionText, model.TEAM_SETTINGS_DEFAULT_CUSTOM_DESCRIPTION_TEXT),
   322  		"isdefault_user_status_away_timeout":        isDefault(*cfg.TeamSettings.UserStatusAwayTimeout, model.TEAM_SETTINGS_DEFAULT_USER_STATUS_AWAY_TIMEOUT),
   323  		"restrict_private_channel_manage_members":   *cfg.TeamSettings.DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManageMembers,
   324  		"enable_X_to_leave_channels_from_LHS":       *cfg.TeamSettings.EnableXToLeaveChannelsFromLHS,
   325  		"experimental_enable_automatic_replies":     *cfg.TeamSettings.ExperimentalEnableAutomaticReplies,
   326  		"experimental_town_square_is_hidden_in_lhs": *cfg.TeamSettings.ExperimentalHideTownSquareinLHS,
   327  		"experimental_town_square_is_read_only":     *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly,
   328  		"experimental_primary_team":                 isDefault(*cfg.TeamSettings.ExperimentalPrimaryTeam, ""),
   329  		"experimental_default_channels":             len(cfg.TeamSettings.ExperimentalDefaultChannels),
   330  	})
   331  
   332  	a.SendDiagnostic(TRACK_CONFIG_CLIENT_REQ, map[string]interface{}{
   333  		"android_latest_version": cfg.ClientRequirements.AndroidLatestVersion,
   334  		"android_min_version":    cfg.ClientRequirements.AndroidMinVersion,
   335  		"desktop_latest_version": cfg.ClientRequirements.DesktopLatestVersion,
   336  		"desktop_min_version":    cfg.ClientRequirements.DesktopMinVersion,
   337  		"ios_latest_version":     cfg.ClientRequirements.IosLatestVersion,
   338  		"ios_min_version":        cfg.ClientRequirements.IosMinVersion,
   339  	})
   340  
   341  	a.SendDiagnostic(TRACK_CONFIG_SQL, map[string]interface{}{
   342  		"driver_name":                    *cfg.SqlSettings.DriverName,
   343  		"trace":                          cfg.SqlSettings.Trace,
   344  		"max_idle_conns":                 *cfg.SqlSettings.MaxIdleConns,
   345  		"conn_max_lifetime_milliseconds": *cfg.SqlSettings.ConnMaxLifetimeMilliseconds,
   346  		"max_open_conns":                 *cfg.SqlSettings.MaxOpenConns,
   347  		"data_source_replicas":           len(cfg.SqlSettings.DataSourceReplicas),
   348  		"data_source_search_replicas":    len(cfg.SqlSettings.DataSourceSearchReplicas),
   349  		"query_timeout":                  *cfg.SqlSettings.QueryTimeout,
   350  	})
   351  
   352  	a.SendDiagnostic(TRACK_CONFIG_LOG, map[string]interface{}{
   353  		"enable_console":           cfg.LogSettings.EnableConsole,
   354  		"console_level":            cfg.LogSettings.ConsoleLevel,
   355  		"console_json":             *cfg.LogSettings.ConsoleJson,
   356  		"enable_file":              cfg.LogSettings.EnableFile,
   357  		"file_level":               cfg.LogSettings.FileLevel,
   358  		"file_json":                cfg.LogSettings.FileJson,
   359  		"enable_webhook_debugging": cfg.LogSettings.EnableWebhookDebugging,
   360  		"isdefault_file_location":  isDefault(cfg.LogSettings.FileLocation, ""),
   361  	})
   362  
   363  	a.SendDiagnostic(TRACK_CONFIG_PASSWORD, map[string]interface{}{
   364  		"minimum_length": *cfg.PasswordSettings.MinimumLength,
   365  		"lowercase":      *cfg.PasswordSettings.Lowercase,
   366  		"number":         *cfg.PasswordSettings.Number,
   367  		"uppercase":      *cfg.PasswordSettings.Uppercase,
   368  		"symbol":         *cfg.PasswordSettings.Symbol,
   369  	})
   370  
   371  	a.SendDiagnostic(TRACK_CONFIG_FILE, map[string]interface{}{
   372  		"enable_public_links":     cfg.FileSettings.EnablePublicLink,
   373  		"driver_name":             *cfg.FileSettings.DriverName,
   374  		"isdefault_directory":     isDefault(*cfg.FileSettings.Directory, model.FILE_SETTINGS_DEFAULT_DIRECTORY),
   375  		"isabsolute_directory":    filepath.IsAbs(*cfg.FileSettings.Directory),
   376  		"amazon_s3_ssl":           *cfg.FileSettings.AmazonS3SSL,
   377  		"amazon_s3_sse":           *cfg.FileSettings.AmazonS3SSE,
   378  		"amazon_s3_signv2":        *cfg.FileSettings.AmazonS3SignV2,
   379  		"amazon_s3_trace":         *cfg.FileSettings.AmazonS3Trace,
   380  		"max_file_size":           *cfg.FileSettings.MaxFileSize,
   381  		"enable_file_attachments": *cfg.FileSettings.EnableFileAttachments,
   382  		"enable_mobile_upload":    *cfg.FileSettings.EnableMobileUpload,
   383  		"enable_mobile_download":  *cfg.FileSettings.EnableMobileDownload,
   384  	})
   385  
   386  	a.SendDiagnostic(TRACK_CONFIG_EMAIL, map[string]interface{}{
   387  		"enable_sign_up_with_email":            cfg.EmailSettings.EnableSignUpWithEmail,
   388  		"enable_sign_in_with_email":            *cfg.EmailSettings.EnableSignInWithEmail,
   389  		"enable_sign_in_with_username":         *cfg.EmailSettings.EnableSignInWithUsername,
   390  		"require_email_verification":           cfg.EmailSettings.RequireEmailVerification,
   391  		"send_email_notifications":             cfg.EmailSettings.SendEmailNotifications,
   392  		"use_channel_in_email_notifications":   *cfg.EmailSettings.UseChannelInEmailNotifications,
   393  		"email_notification_contents_type":     *cfg.EmailSettings.EmailNotificationContentsType,
   394  		"enable_smtp_auth":                     *cfg.EmailSettings.EnableSMTPAuth,
   395  		"connection_security":                  cfg.EmailSettings.ConnectionSecurity,
   396  		"send_push_notifications":              *cfg.EmailSettings.SendPushNotifications,
   397  		"push_notification_contents":           *cfg.EmailSettings.PushNotificationContents,
   398  		"enable_email_batching":                *cfg.EmailSettings.EnableEmailBatching,
   399  		"email_batching_buffer_size":           *cfg.EmailSettings.EmailBatchingBufferSize,
   400  		"email_batching_interval":              *cfg.EmailSettings.EmailBatchingInterval,
   401  		"enable_preview_mode_banner":           *cfg.EmailSettings.EnablePreviewModeBanner,
   402  		"isdefault_feedback_name":              isDefault(cfg.EmailSettings.FeedbackName, ""),
   403  		"isdefault_feedback_email":             isDefault(cfg.EmailSettings.FeedbackEmail, ""),
   404  		"isdefault_reply_to_address":           isDefault(cfg.EmailSettings.ReplyToAddress, ""),
   405  		"isdefault_feedback_organization":      isDefault(*cfg.EmailSettings.FeedbackOrganization, model.EMAIL_SETTINGS_DEFAULT_FEEDBACK_ORGANIZATION),
   406  		"skip_server_certificate_verification": *cfg.EmailSettings.SkipServerCertificateVerification,
   407  		"isdefault_login_button_color":         isDefault(*cfg.EmailSettings.LoginButtonColor, ""),
   408  		"isdefault_login_button_border_color":  isDefault(*cfg.EmailSettings.LoginButtonBorderColor, ""),
   409  		"isdefault_login_button_text_color":    isDefault(*cfg.EmailSettings.LoginButtonTextColor, ""),
   410  	})
   411  
   412  	a.SendDiagnostic(TRACK_CONFIG_RATE, map[string]interface{}{
   413  		"enable_rate_limiter":      *cfg.RateLimitSettings.Enable,
   414  		"vary_by_remote_address":   *cfg.RateLimitSettings.VaryByRemoteAddr,
   415  		"vary_by_user":             *cfg.RateLimitSettings.VaryByUser,
   416  		"per_sec":                  *cfg.RateLimitSettings.PerSec,
   417  		"max_burst":                *cfg.RateLimitSettings.MaxBurst,
   418  		"memory_store_size":        *cfg.RateLimitSettings.MemoryStoreSize,
   419  		"isdefault_vary_by_header": isDefault(cfg.RateLimitSettings.VaryByHeader, ""),
   420  	})
   421  
   422  	a.SendDiagnostic(TRACK_CONFIG_PRIVACY, map[string]interface{}{
   423  		"show_email_address": cfg.PrivacySettings.ShowEmailAddress,
   424  		"show_full_name":     cfg.PrivacySettings.ShowFullName,
   425  	})
   426  
   427  	a.SendDiagnostic(TRACK_CONFIG_THEME, map[string]interface{}{
   428  		"enable_theme_selection":  *cfg.ThemeSettings.EnableThemeSelection,
   429  		"isdefault_default_theme": isDefault(*cfg.ThemeSettings.DefaultTheme, model.TEAM_SETTINGS_DEFAULT_TEAM_TEXT),
   430  		"allow_custom_themes":     *cfg.ThemeSettings.AllowCustomThemes,
   431  		"allowed_themes":          len(cfg.ThemeSettings.AllowedThemes),
   432  	})
   433  
   434  	a.SendDiagnostic(TRACK_CONFIG_OAUTH, map[string]interface{}{
   435  		"enable_gitlab":    cfg.GitLabSettings.Enable,
   436  		"enable_google":    cfg.GoogleSettings.Enable,
   437  		"enable_office365": cfg.Office365Settings.Enable,
   438  	})
   439  
   440  	a.SendDiagnostic(TRACK_CONFIG_SUPPORT, map[string]interface{}{
   441  		"isdefault_terms_of_service_link":              isDefault(*cfg.SupportSettings.TermsOfServiceLink, model.SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK),
   442  		"isdefault_privacy_policy_link":                isDefault(*cfg.SupportSettings.PrivacyPolicyLink, model.SUPPORT_SETTINGS_DEFAULT_PRIVACY_POLICY_LINK),
   443  		"isdefault_about_link":                         isDefault(*cfg.SupportSettings.AboutLink, model.SUPPORT_SETTINGS_DEFAULT_ABOUT_LINK),
   444  		"isdefault_help_link":                          isDefault(*cfg.SupportSettings.HelpLink, model.SUPPORT_SETTINGS_DEFAULT_HELP_LINK),
   445  		"isdefault_report_a_problem_link":              isDefault(*cfg.SupportSettings.ReportAProblemLink, model.SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK),
   446  		"isdefault_support_email":                      isDefault(*cfg.SupportSettings.SupportEmail, model.SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL),
   447  		"custom_terms_of_service_enabled":              *cfg.SupportSettings.CustomTermsOfServiceEnabled,
   448  		"custom_terms_of_service_re_acceptance_period": *cfg.SupportSettings.CustomTermsOfServiceReAcceptancePeriod,
   449  	})
   450  
   451  	a.SendDiagnostic(TRACK_CONFIG_LDAP, map[string]interface{}{
   452  		"enable":                                 *cfg.LdapSettings.Enable,
   453  		"enable_sync":                            *cfg.LdapSettings.EnableSync,
   454  		"connection_security":                    *cfg.LdapSettings.ConnectionSecurity,
   455  		"skip_certificate_verification":          *cfg.LdapSettings.SkipCertificateVerification,
   456  		"sync_interval_minutes":                  *cfg.LdapSettings.SyncIntervalMinutes,
   457  		"query_timeout":                          *cfg.LdapSettings.QueryTimeout,
   458  		"max_page_size":                          *cfg.LdapSettings.MaxPageSize,
   459  		"isdefault_first_name_attribute":         isDefault(*cfg.LdapSettings.FirstNameAttribute, model.LDAP_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE),
   460  		"isdefault_last_name_attribute":          isDefault(*cfg.LdapSettings.LastNameAttribute, model.LDAP_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE),
   461  		"isdefault_email_attribute":              isDefault(*cfg.LdapSettings.EmailAttribute, model.LDAP_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE),
   462  		"isdefault_username_attribute":           isDefault(*cfg.LdapSettings.UsernameAttribute, model.LDAP_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE),
   463  		"isdefault_nickname_attribute":           isDefault(*cfg.LdapSettings.NicknameAttribute, model.LDAP_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE),
   464  		"isdefault_id_attribute":                 isDefault(*cfg.LdapSettings.IdAttribute, model.LDAP_SETTINGS_DEFAULT_ID_ATTRIBUTE),
   465  		"isdefault_position_attribute":           isDefault(*cfg.LdapSettings.PositionAttribute, model.LDAP_SETTINGS_DEFAULT_POSITION_ATTRIBUTE),
   466  		"isdefault_login_id_attribute":           isDefault(*cfg.LdapSettings.LoginIdAttribute, ""),
   467  		"isdefault_login_field_name":             isDefault(*cfg.LdapSettings.LoginFieldName, model.LDAP_SETTINGS_DEFAULT_LOGIN_FIELD_NAME),
   468  		"isdefault_login_button_color":           isDefault(*cfg.LdapSettings.LoginButtonColor, ""),
   469  		"isdefault_login_button_border_color":    isDefault(*cfg.LdapSettings.LoginButtonBorderColor, ""),
   470  		"isdefault_login_button_text_color":      isDefault(*cfg.LdapSettings.LoginButtonTextColor, ""),
   471  		"isempty_group_filter":                   isDefault(*cfg.LdapSettings.GroupFilter, ""),
   472  		"isdefault_group_display_name_attribute": isDefault(*cfg.LdapSettings.GroupDisplayNameAttribute, model.LDAP_SETTINGS_DEFAULT_GROUP_DISPLAY_NAME_ATTRIBUTE),
   473  		"isdefault_group_id_attribute":           isDefault(*cfg.LdapSettings.GroupIdAttribute, model.LDAP_SETTINGS_DEFAULT_GROUP_ID_ATTRIBUTE),
   474  	})
   475  
   476  	a.SendDiagnostic(TRACK_CONFIG_COMPLIANCE, map[string]interface{}{
   477  		"enable":       *cfg.ComplianceSettings.Enable,
   478  		"enable_daily": *cfg.ComplianceSettings.EnableDaily,
   479  	})
   480  
   481  	a.SendDiagnostic(TRACK_CONFIG_LOCALIZATION, map[string]interface{}{
   482  		"default_server_locale": *cfg.LocalizationSettings.DefaultServerLocale,
   483  		"default_client_locale": *cfg.LocalizationSettings.DefaultClientLocale,
   484  		"available_locales":     *cfg.LocalizationSettings.AvailableLocales,
   485  	})
   486  
   487  	a.SendDiagnostic(TRACK_CONFIG_SAML, map[string]interface{}{
   488  		"enable":                              *cfg.SamlSettings.Enable,
   489  		"enable_sync_with_ldap":               *cfg.SamlSettings.EnableSyncWithLdap,
   490  		"enable_sync_with_ldap_include_auth":  *cfg.SamlSettings.EnableSyncWithLdapIncludeAuth,
   491  		"verify":                              *cfg.SamlSettings.Verify,
   492  		"encrypt":                             *cfg.SamlSettings.Encrypt,
   493  		"isdefault_scoping_idp_provider_id":   isDefault(*cfg.SamlSettings.ScopingIDPProviderId, ""),
   494  		"isdefault_scoping_idp_name":          isDefault(*cfg.SamlSettings.ScopingIDPName, ""),
   495  		"isdefault_id_attribute":              isDefault(*cfg.SamlSettings.IdAttribute, model.SAML_SETTINGS_DEFAULT_ID_ATTRIBUTE),
   496  		"isdefault_first_name_attribute":      isDefault(*cfg.SamlSettings.FirstNameAttribute, model.SAML_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE),
   497  		"isdefault_last_name_attribute":       isDefault(*cfg.SamlSettings.LastNameAttribute, model.SAML_SETTINGS_DEFAULT_LAST_NAME_ATTRIBUTE),
   498  		"isdefault_email_attribute":           isDefault(*cfg.SamlSettings.EmailAttribute, model.SAML_SETTINGS_DEFAULT_EMAIL_ATTRIBUTE),
   499  		"isdefault_username_attribute":        isDefault(*cfg.SamlSettings.UsernameAttribute, model.SAML_SETTINGS_DEFAULT_USERNAME_ATTRIBUTE),
   500  		"isdefault_nickname_attribute":        isDefault(*cfg.SamlSettings.NicknameAttribute, model.SAML_SETTINGS_DEFAULT_NICKNAME_ATTRIBUTE),
   501  		"isdefault_locale_attribute":          isDefault(*cfg.SamlSettings.LocaleAttribute, model.SAML_SETTINGS_DEFAULT_LOCALE_ATTRIBUTE),
   502  		"isdefault_position_attribute":        isDefault(*cfg.SamlSettings.PositionAttribute, model.SAML_SETTINGS_DEFAULT_POSITION_ATTRIBUTE),
   503  		"isdefault_login_button_text":         isDefault(*cfg.SamlSettings.LoginButtonText, model.USER_AUTH_SERVICE_SAML_TEXT),
   504  		"isdefault_login_button_color":        isDefault(*cfg.SamlSettings.LoginButtonColor, ""),
   505  		"isdefault_login_button_border_color": isDefault(*cfg.SamlSettings.LoginButtonBorderColor, ""),
   506  		"isdefault_login_button_text_color":   isDefault(*cfg.SamlSettings.LoginButtonTextColor, ""),
   507  	})
   508  
   509  	a.SendDiagnostic(TRACK_CONFIG_CLUSTER, map[string]interface{}{
   510  		"enable":                  *cfg.ClusterSettings.Enable,
   511  		"use_ip_address":          *cfg.ClusterSettings.UseIpAddress,
   512  		"use_experimental_gossip": *cfg.ClusterSettings.UseExperimentalGossip,
   513  		"read_only_config":        *cfg.ClusterSettings.ReadOnlyConfig,
   514  	})
   515  
   516  	a.SendDiagnostic(TRACK_CONFIG_METRICS, map[string]interface{}{
   517  		"enable":             *cfg.MetricsSettings.Enable,
   518  		"block_profile_rate": *cfg.MetricsSettings.BlockProfileRate,
   519  	})
   520  
   521  	a.SendDiagnostic(TRACK_CONFIG_NATIVEAPP, map[string]interface{}{
   522  		"isdefault_app_download_link":         isDefault(*cfg.NativeAppSettings.AppDownloadLink, model.NATIVEAPP_SETTINGS_DEFAULT_APP_DOWNLOAD_LINK),
   523  		"isdefault_android_app_download_link": isDefault(*cfg.NativeAppSettings.AndroidAppDownloadLink, model.NATIVEAPP_SETTINGS_DEFAULT_ANDROID_APP_DOWNLOAD_LINK),
   524  		"isdefault_iosapp_download_link":      isDefault(*cfg.NativeAppSettings.IosAppDownloadLink, model.NATIVEAPP_SETTINGS_DEFAULT_IOS_APP_DOWNLOAD_LINK),
   525  	})
   526  
   527  	a.SendDiagnostic(TRACK_CONFIG_EXPERIMENTAL, map[string]interface{}{
   528  		"client_side_cert_enable":            *cfg.ExperimentalSettings.ClientSideCertEnable,
   529  		"isdefault_client_side_cert_check":   isDefault(*cfg.ExperimentalSettings.ClientSideCertCheck, model.CLIENT_SIDE_CERT_CHECK_PRIMARY_AUTH),
   530  		"enable_post_metadata":               !*cfg.ExperimentalSettings.DisablePostMetadata,
   531  		"link_metadata_timeout_milliseconds": *cfg.ExperimentalSettings.LinkMetadataTimeoutMilliseconds,
   532  		"enable_click_to_reply":              *cfg.ExperimentalSettings.EnableClickToReply,
   533  		"restrict_system_admin":              *cfg.ExperimentalSettings.RestrictSystemAdmin,
   534  	})
   535  
   536  	a.SendDiagnostic(TRACK_CONFIG_ANALYTICS, map[string]interface{}{
   537  		"isdefault_max_users_for_statistics": isDefault(*cfg.AnalyticsSettings.MaxUsersForStatistics, model.ANALYTICS_SETTINGS_DEFAULT_MAX_USERS_FOR_STATISTICS),
   538  	})
   539  
   540  	a.SendDiagnostic(TRACK_CONFIG_ANNOUNCEMENT, map[string]interface{}{
   541  		"enable_banner":               *cfg.AnnouncementSettings.EnableBanner,
   542  		"isdefault_banner_color":      isDefault(*cfg.AnnouncementSettings.BannerColor, model.ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_COLOR),
   543  		"isdefault_banner_text_color": isDefault(*cfg.AnnouncementSettings.BannerTextColor, model.ANNOUNCEMENT_SETTINGS_DEFAULT_BANNER_TEXT_COLOR),
   544  		"allow_banner_dismissal":      *cfg.AnnouncementSettings.AllowBannerDismissal,
   545  	})
   546  
   547  	a.SendDiagnostic(TRACK_CONFIG_ELASTICSEARCH, map[string]interface{}{
   548  		"isdefault_connection_url":          isDefault(*cfg.ElasticsearchSettings.ConnectionUrl, model.ELASTICSEARCH_SETTINGS_DEFAULT_CONNECTION_URL),
   549  		"isdefault_username":                isDefault(*cfg.ElasticsearchSettings.Username, model.ELASTICSEARCH_SETTINGS_DEFAULT_USERNAME),
   550  		"isdefault_password":                isDefault(*cfg.ElasticsearchSettings.Password, model.ELASTICSEARCH_SETTINGS_DEFAULT_PASSWORD),
   551  		"enable_indexing":                   *cfg.ElasticsearchSettings.EnableIndexing,
   552  		"enable_searching":                  *cfg.ElasticsearchSettings.EnableSearching,
   553  		"enable_autocomplete":               *cfg.ElasticsearchSettings.EnableAutocomplete,
   554  		"sniff":                             *cfg.ElasticsearchSettings.Sniff,
   555  		"post_index_replicas":               *cfg.ElasticsearchSettings.PostIndexReplicas,
   556  		"post_index_shards":                 *cfg.ElasticsearchSettings.PostIndexShards,
   557  		"channel_index_replicas":            *cfg.ElasticsearchSettings.ChannelIndexReplicas,
   558  		"channel_index_shards":              *cfg.ElasticsearchSettings.ChannelIndexShards,
   559  		"user_index_replicas":               *cfg.ElasticsearchSettings.UserIndexReplicas,
   560  		"user_index_shards":                 *cfg.ElasticsearchSettings.UserIndexShards,
   561  		"isdefault_index_prefix":            isDefault(*cfg.ElasticsearchSettings.IndexPrefix, model.ELASTICSEARCH_SETTINGS_DEFAULT_INDEX_PREFIX),
   562  		"live_indexing_batch_size":          *cfg.ElasticsearchSettings.LiveIndexingBatchSize,
   563  		"bulk_indexing_time_window_seconds": *cfg.ElasticsearchSettings.BulkIndexingTimeWindowSeconds,
   564  		"request_timeout_seconds":           *cfg.ElasticsearchSettings.RequestTimeoutSeconds,
   565  	})
   566  
   567  	a.SendDiagnostic(TRACK_CONFIG_PLUGIN, map[string]interface{}{
   568  		"enable_jira":       pluginSetting(&cfg.PluginSettings, "jira", "enabled", false),
   569  		"enable_nps":        pluginActivated(cfg.PluginSettings.PluginStates, "com.mattermost.nps"),
   570  		"enable_nps_survey": pluginSetting(&cfg.PluginSettings, "com.mattermost.nps", "enablesurvey", false),
   571  		"enable_zoom":       pluginActivated(cfg.PluginSettings.PluginStates, "zoom"),
   572  		"enable":            *cfg.PluginSettings.Enable,
   573  		"enable_uploads":    *cfg.PluginSettings.EnableUploads,
   574  	})
   575  
   576  	a.SendDiagnostic(TRACK_CONFIG_DATA_RETENTION, map[string]interface{}{
   577  		"enable_message_deletion": *cfg.DataRetentionSettings.EnableMessageDeletion,
   578  		"enable_file_deletion":    *cfg.DataRetentionSettings.EnableFileDeletion,
   579  		"message_retention_days":  *cfg.DataRetentionSettings.MessageRetentionDays,
   580  		"file_retention_days":     *cfg.DataRetentionSettings.FileRetentionDays,
   581  		"deletion_job_start_time": *cfg.DataRetentionSettings.DeletionJobStartTime,
   582  	})
   583  
   584  	a.SendDiagnostic(TRACK_CONFIG_MESSAGE_EXPORT, map[string]interface{}{
   585  		"enable_message_export":                 *cfg.MessageExportSettings.EnableExport,
   586  		"export_format":                         *cfg.MessageExportSettings.ExportFormat,
   587  		"daily_run_time":                        *cfg.MessageExportSettings.DailyRunTime,
   588  		"default_export_from_timestamp":         *cfg.MessageExportSettings.ExportFromTimestamp,
   589  		"batch_size":                            *cfg.MessageExportSettings.BatchSize,
   590  		"global_relay_customer_type":            *cfg.MessageExportSettings.GlobalRelaySettings.CustomerType,
   591  		"is_default_global_relay_smtp_username": isDefault(*cfg.MessageExportSettings.GlobalRelaySettings.SmtpUsername, ""),
   592  		"is_default_global_relay_smtp_password": isDefault(*cfg.MessageExportSettings.GlobalRelaySettings.SmtpPassword, ""),
   593  		"is_default_global_relay_email_address": isDefault(*cfg.MessageExportSettings.GlobalRelaySettings.EmailAddress, ""),
   594  	})
   595  
   596  	a.SendDiagnostic(TRACK_CONFIG_DISPLAY, map[string]interface{}{
   597  		"experimental_timezone":        *cfg.DisplaySettings.ExperimentalTimezone,
   598  		"isdefault_custom_url_schemes": len(cfg.DisplaySettings.CustomUrlSchemes) != 0,
   599  	})
   600  
   601  	a.SendDiagnostic(TRACK_CONFIG_IMAGE_PROXY, map[string]interface{}{
   602  		"enable":                               *cfg.ImageProxySettings.Enable,
   603  		"image_proxy_type":                     *cfg.ImageProxySettings.ImageProxyType,
   604  		"isdefault_remote_image_proxy_url":     isDefault(*cfg.ImageProxySettings.RemoteImageProxyURL, ""),
   605  		"isdefault_remote_image_proxy_options": isDefault(*cfg.ImageProxySettings.RemoteImageProxyOptions, ""),
   606  	})
   607  }
   608  
   609  func (a *App) trackLicense() {
   610  	if license := a.License(); license != nil {
   611  		data := map[string]interface{}{
   612  			"customer_id": license.Customer.Id,
   613  			"license_id":  license.Id,
   614  			"issued":      license.IssuedAt,
   615  			"start":       license.StartsAt,
   616  			"expire":      license.ExpiresAt,
   617  			"users":       *license.Features.Users,
   618  			"edition":     license.SkuShortName,
   619  		}
   620  
   621  		features := license.Features.ToMap()
   622  		for featureName, featureValue := range features {
   623  			data["feature_"+featureName] = featureValue
   624  		}
   625  
   626  		a.SendDiagnostic(TRACK_LICENSE, data)
   627  	}
   628  }
   629  
   630  func (a *App) trackPlugins() {
   631  	pluginsEnvironment := a.GetPluginsEnvironment()
   632  	if pluginsEnvironment == nil {
   633  		return
   634  	}
   635  
   636  	totalEnabledCount := 0
   637  	webappEnabledCount := 0
   638  	backendEnabledCount := 0
   639  	totalDisabledCount := 0
   640  	webappDisabledCount := 0
   641  	backendDisabledCount := 0
   642  	brokenManifestCount := 0
   643  	settingsCount := 0
   644  
   645  	pluginStates := a.Config().PluginSettings.PluginStates
   646  	plugins, _ := pluginsEnvironment.Available()
   647  
   648  	if pluginStates != nil && plugins != nil {
   649  		for _, plugin := range plugins {
   650  			if plugin.Manifest == nil {
   651  				brokenManifestCount += 1
   652  				continue
   653  			}
   654  			if state, ok := pluginStates[plugin.Manifest.Id]; ok && state.Enable {
   655  				totalEnabledCount += 1
   656  				if plugin.Manifest.HasServer() {
   657  					backendEnabledCount += 1
   658  				}
   659  				if plugin.Manifest.HasWebapp() {
   660  					webappEnabledCount += 1
   661  				}
   662  			} else {
   663  				totalDisabledCount += 1
   664  				if plugin.Manifest.HasServer() {
   665  					backendDisabledCount += 1
   666  				}
   667  				if plugin.Manifest.HasWebapp() {
   668  					webappDisabledCount += 1
   669  				}
   670  			}
   671  			if plugin.Manifest.SettingsSchema != nil {
   672  				settingsCount += 1
   673  			}
   674  		}
   675  	} else {
   676  		totalEnabledCount = -1  // -1 to indicate disabled or error
   677  		totalDisabledCount = -1 // -1 to indicate disabled or error
   678  	}
   679  
   680  	a.SendDiagnostic(TRACK_PLUGINS, map[string]interface{}{
   681  		"enabled_plugins":               totalEnabledCount,
   682  		"enabled_webapp_plugins":        webappEnabledCount,
   683  		"enabled_backend_plugins":       backendEnabledCount,
   684  		"disabled_plugins":              totalDisabledCount,
   685  		"disabled_webapp_plugins":       webappDisabledCount,
   686  		"disabled_backend_plugins":      backendDisabledCount,
   687  		"plugins_with_settings":         settingsCount,
   688  		"plugins_with_broken_manifests": brokenManifestCount,
   689  	})
   690  }
   691  
   692  func (a *App) trackServer() {
   693  	data := map[string]interface{}{
   694  		"edition":          model.BuildEnterpriseReady,
   695  		"version":          model.CurrentVersion,
   696  		"database_type":    *a.Config().SqlSettings.DriverName,
   697  		"operating_system": runtime.GOOS,
   698  	}
   699  
   700  	if scr := <-a.Srv.Store.User().AnalyticsGetSystemAdminCount(); scr.Err == nil {
   701  		data["system_admins"] = scr.Data.(int64)
   702  	}
   703  
   704  	a.SendDiagnostic(TRACK_SERVER, data)
   705  }
   706  
   707  func (a *App) trackPermissions() {
   708  	phase1Complete := false
   709  	if ph1res := <-a.Srv.Store.System().GetByName(ADVANCED_PERMISSIONS_MIGRATION_KEY); ph1res.Err == nil {
   710  		phase1Complete = true
   711  	}
   712  
   713  	phase2Complete := false
   714  	if ph2res := <-a.Srv.Store.System().GetByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2); ph2res.Err == nil {
   715  		phase2Complete = true
   716  	}
   717  
   718  	a.SendDiagnostic(TRACK_PERMISSIONS_GENERAL, map[string]interface{}{
   719  		"phase_1_migration_complete": phase1Complete,
   720  		"phase_2_migration_complete": phase2Complete,
   721  	})
   722  
   723  	systemAdminPermissions := ""
   724  	if role, err := a.GetRoleByName(model.SYSTEM_ADMIN_ROLE_ID); err == nil {
   725  		systemAdminPermissions = strings.Join(role.Permissions, " ")
   726  	}
   727  
   728  	systemUserPermissions := ""
   729  	if role, err := a.GetRoleByName(model.SYSTEM_USER_ROLE_ID); err == nil {
   730  		systemUserPermissions = strings.Join(role.Permissions, " ")
   731  	}
   732  
   733  	teamAdminPermissions := ""
   734  	if role, err := a.GetRoleByName(model.TEAM_ADMIN_ROLE_ID); err == nil {
   735  		teamAdminPermissions = strings.Join(role.Permissions, " ")
   736  	}
   737  
   738  	teamUserPermissions := ""
   739  	if role, err := a.GetRoleByName(model.TEAM_USER_ROLE_ID); err == nil {
   740  		teamUserPermissions = strings.Join(role.Permissions, " ")
   741  	}
   742  
   743  	channelAdminPermissions := ""
   744  	if role, err := a.GetRoleByName(model.CHANNEL_ADMIN_ROLE_ID); err == nil {
   745  		channelAdminPermissions = strings.Join(role.Permissions, " ")
   746  	}
   747  
   748  	channelUserPermissions := ""
   749  	if role, err := a.GetRoleByName(model.CHANNEL_USER_ROLE_ID); err == nil {
   750  		systemAdminPermissions = strings.Join(role.Permissions, " ")
   751  	}
   752  
   753  	a.SendDiagnostic(TRACK_PERMISSIONS_SYSTEM_SCHEME, map[string]interface{}{
   754  		"system_admin_permissions":  systemAdminPermissions,
   755  		"system_user_permissions":   systemUserPermissions,
   756  		"team_admin_permissions":    teamAdminPermissions,
   757  		"team_user_permissions":     teamUserPermissions,
   758  		"channel_admin_permissions": channelAdminPermissions,
   759  		"channel_user_permissions":  channelUserPermissions,
   760  	})
   761  
   762  	if schemes, err := a.GetSchemes(model.SCHEME_SCOPE_TEAM, 0, 100); err == nil {
   763  		for _, scheme := range schemes {
   764  			teamAdminPermissions := ""
   765  			if role, err := a.GetRoleByName(scheme.DefaultTeamAdminRole); err == nil {
   766  				teamAdminPermissions = strings.Join(role.Permissions, " ")
   767  			}
   768  
   769  			teamUserPermissions := ""
   770  			if role, err := a.GetRoleByName(scheme.DefaultTeamUserRole); err == nil {
   771  				teamUserPermissions = strings.Join(role.Permissions, " ")
   772  			}
   773  
   774  			channelAdminPermissions := ""
   775  			if role, err := a.GetRoleByName(scheme.DefaultChannelAdminRole); err == nil {
   776  				channelAdminPermissions = strings.Join(role.Permissions, " ")
   777  			}
   778  
   779  			channelUserPermissions := ""
   780  			if role, err := a.GetRoleByName(scheme.DefaultChannelUserRole); err == nil {
   781  				systemAdminPermissions = strings.Join(role.Permissions, " ")
   782  			}
   783  
   784  			var count int64 = 0
   785  			if res := <-a.Srv.Store.Team().AnalyticsGetTeamCountForScheme(scheme.Id); res.Err == nil {
   786  				count = res.Data.(int64)
   787  			}
   788  
   789  			a.SendDiagnostic(TRACK_PERMISSIONS_TEAM_SCHEMES, map[string]interface{}{
   790  				"scheme_id":                 scheme.Id,
   791  				"team_admin_permissions":    teamAdminPermissions,
   792  				"team_user_permissions":     teamUserPermissions,
   793  				"channel_admin_permissions": channelAdminPermissions,
   794  				"channel_user_permissions":  channelUserPermissions,
   795  				"team_count":                count,
   796  			})
   797  		}
   798  	}
   799  }