From f6f025aeaa8d7308af992d127e08deedc9295cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Thu, 9 Apr 2020 11:05:43 +0200 Subject: [PATCH] Adding guest accounts count telemetry (#14257) * Adding guest accounts count telemetry * Adding missed methods to the opentracing an timer layer --- app/diagnostics.go | 6 ++ store/opentracing_layer.go | 90 ++++++++++++++++++++++++++++++ store/sqlstore/user_store.go | 8 +++ store/store.go | 1 + store/storetest/mocks/UserStore.go | 23 ++++++++ store/storetest/user_store.go | 37 ++++++++++++ store/timer_layer.go | 80 ++++++++++++++++++++++++++ 7 files changed, 245 insertions(+) diff --git a/app/diagnostics.go b/app/diagnostics.go index dceb613270..36545072eb 100644 --- a/app/diagnostics.go +++ b/app/diagnostics.go @@ -123,6 +123,7 @@ func pluginVersion(pluginsAvailable []*model.BundleInfo, pluginId string) string func (a *App) trackActivity() { var userCount int64 + var guestAccountsCount int64 var botAccountsCount int64 var inactiveUserCount int64 var publicChannelCount int64 @@ -155,6 +156,10 @@ func (a *App) trackActivity() { userCount = count } + if count, err := a.Srv().Store.User().AnalyticsGetGuestCount(); err == nil { + guestAccountsCount = count + } + if count, err := a.Srv().Store.User().Count(model.UserCountOptions{IncludeBotAccounts: true, ExcludeRegularUsers: true}); err == nil { botAccountsCount = count } @@ -225,6 +230,7 @@ func (a *App) trackActivity() { a.SendDiagnostic(TRACK_ACTIVITY, map[string]interface{}{ "registered_users": userCount, "bot_accounts": botAccountsCount, + "guest_accounts": guestAccountsCount, "active_users_daily": activeUsersDailyCount, "active_users_monthly": activeUsersMonthlyCount, "registered_deactivated_users": inactiveUserCount, diff --git a/store/opentracing_layer.go b/store/opentracing_layer.go index 420fd73041..6027b4c0f9 100644 --- a/store/opentracing_layer.go +++ b/store/opentracing_layer.go @@ -1588,6 +1588,24 @@ func (s *OpenTracingLayerChannelStore) RemoveMember(channelId string, userId str return resultVar0 } +func (s *OpenTracingLayerChannelStore) RemoveMembers(channelId string, userIds []string) *model.AppError { + origCtx := s.Root.Store.Context() + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.RemoveMembers") + s.Root.Store.SetContext(newCtx) + defer func() { + s.Root.Store.SetContext(origCtx) + }() + + defer span.Finish() + resultVar0 := s.ChannelStore.RemoveMembers(channelId, userIds) + if resultVar0 != nil { + span.LogFields(spanlog.Error(resultVar0)) + ext.Error.Set(span, true) + } + + return resultVar0 +} + func (s *OpenTracingLayerChannelStore) ResetAllChannelSchemes() *model.AppError { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.ResetAllChannelSchemes") @@ -5431,6 +5449,42 @@ func (s *OpenTracingLayerRoleStore) Save(role *model.Role) (*model.Role, *model. return resultVar0, resultVar1 } +func (s *OpenTracingLayerSchemeStore) CountByScope(scope string) (int64, *model.AppError) { + origCtx := s.Root.Store.Context() + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SchemeStore.CountByScope") + s.Root.Store.SetContext(newCtx) + defer func() { + s.Root.Store.SetContext(origCtx) + }() + + defer span.Finish() + resultVar0, resultVar1 := s.SchemeStore.CountByScope(scope) + if resultVar1 != nil { + span.LogFields(spanlog.Error(resultVar1)) + ext.Error.Set(span, true) + } + + return resultVar0, resultVar1 +} + +func (s *OpenTracingLayerSchemeStore) CountWithoutPermission(scope string, permissionID string, roleScope model.RoleScope, roleType model.RoleType) (int64, *model.AppError) { + origCtx := s.Root.Store.Context() + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SchemeStore.CountWithoutPermission") + s.Root.Store.SetContext(newCtx) + defer func() { + s.Root.Store.SetContext(origCtx) + }() + + defer span.Finish() + resultVar0, resultVar1 := s.SchemeStore.CountWithoutPermission(scope, permissionID, roleScope, roleType) + if resultVar1 != nil { + span.LogFields(spanlog.Error(resultVar1)) + ext.Error.Set(span, true) + } + + return resultVar0, resultVar1 +} + func (s *OpenTracingLayerSchemeStore) Delete(schemeId string) (*model.Scheme, *model.AppError) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SchemeStore.Delete") @@ -6658,6 +6712,24 @@ func (s *OpenTracingLayerTeamStore) RemoveMember(teamId string, userId string) * return resultVar0 } +func (s *OpenTracingLayerTeamStore) RemoveMembers(teamId string, userIds []string) *model.AppError { + origCtx := s.Root.Store.Context() + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "TeamStore.RemoveMembers") + s.Root.Store.SetContext(newCtx) + defer func() { + s.Root.Store.SetContext(origCtx) + }() + + defer span.Finish() + resultVar0 := s.TeamStore.RemoveMembers(teamId, userIds) + if resultVar0 != nil { + span.LogFields(spanlog.Error(resultVar0)) + ext.Error.Set(span, true) + } + + return resultVar0 +} + func (s *OpenTracingLayerTeamStore) ResetAllTeamSchemes() *model.AppError { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "TeamStore.ResetAllTeamSchemes") @@ -7067,6 +7139,24 @@ func (s *OpenTracingLayerUserStore) AnalyticsActiveCount(time int64, options mod return resultVar0, resultVar1 } +func (s *OpenTracingLayerUserStore) AnalyticsGetGuestCount() (int64, *model.AppError) { + origCtx := s.Root.Store.Context() + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "UserStore.AnalyticsGetGuestCount") + s.Root.Store.SetContext(newCtx) + defer func() { + s.Root.Store.SetContext(origCtx) + }() + + defer span.Finish() + resultVar0, resultVar1 := s.UserStore.AnalyticsGetGuestCount() + if resultVar1 != nil { + span.LogFields(spanlog.Error(resultVar1)) + ext.Error.Set(span, true) + } + + return resultVar0, resultVar1 +} + func (s *OpenTracingLayerUserStore) AnalyticsGetInactiveUsersCount() (int64, *model.AppError) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "UserStore.AnalyticsGetInactiveUsersCount") diff --git a/store/sqlstore/user_store.go b/store/sqlstore/user_store.go index 0ef485bde4..3185e55ce6 100644 --- a/store/sqlstore/user_store.go +++ b/store/sqlstore/user_store.go @@ -1290,6 +1290,14 @@ func (us SqlUserStore) AnalyticsGetInactiveUsersCount() (int64, *model.AppError) return count, nil } +func (us SqlUserStore) AnalyticsGetGuestCount() (int64, *model.AppError) { + count, err := us.GetReplica().SelectInt("SELECT count(*) FROM Users WHERE Roles LIKE :Roles and DeleteAt = 0", map[string]interface{}{"Roles": "%system_guest%"}) + if err != nil { + return int64(0), model.NewAppError("SqlUserStore.AnalyticsGetSystemAdminCount", "store.sql_user.analytics_get_system_admin_count.app_error", nil, err.Error(), http.StatusInternalServerError) + } + return count, nil +} + func (us SqlUserStore) AnalyticsGetSystemAdminCount() (int64, *model.AppError) { count, err := us.GetReplica().SelectInt("SELECT count(*) FROM Users WHERE Roles LIKE :Roles and DeleteAt = 0", map[string]interface{}{"Roles": "%system_admin%"}) if err != nil { diff --git a/store/store.go b/store/store.go index d4665925ed..61d5062f16 100644 --- a/store/store.go +++ b/store/store.go @@ -315,6 +315,7 @@ type UserStore interface { SearchWithoutTeam(term string, options *model.UserSearchOptions) ([]*model.User, *model.AppError) AnalyticsGetInactiveUsersCount() (int64, *model.AppError) AnalyticsGetSystemAdminCount() (int64, *model.AppError) + AnalyticsGetGuestCount() (int64, *model.AppError) GetProfilesNotInTeam(teamId string, groupConstrained bool, offset int, limit int, viewRestrictions *model.ViewUsersRestrictions) ([]*model.User, *model.AppError) GetEtagForProfilesNotInTeam(teamId string) string ClearAllCustomRoleAssignments() *model.AppError diff --git a/store/storetest/mocks/UserStore.go b/store/storetest/mocks/UserStore.go index 5e3268f8d0..886f1d869f 100644 --- a/store/storetest/mocks/UserStore.go +++ b/store/storetest/mocks/UserStore.go @@ -38,6 +38,29 @@ func (_m *UserStore) AnalyticsActiveCount(time int64, options model.UserCountOpt return r0, r1 } +// AnalyticsGetGuestCount provides a mock function with given fields: +func (_m *UserStore) AnalyticsGetGuestCount() (int64, *model.AppError) { + ret := _m.Called() + + var r0 int64 + if rf, ok := ret.Get(0).(func() int64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(int64) + } + + var r1 *model.AppError + if rf, ok := ret.Get(1).(func() *model.AppError); ok { + r1 = rf() + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*model.AppError) + } + } + + return r0, r1 +} + // AnalyticsGetInactiveUsersCount provides a mock function with given fields: func (_m *UserStore) AnalyticsGetInactiveUsersCount() (int64, *model.AppError) { ret := _m.Called() diff --git a/store/storetest/user_store.go b/store/storetest/user_store.go index a6b5e2f53b..a43fc10e87 100644 --- a/store/storetest/user_store.go +++ b/store/storetest/user_store.go @@ -38,6 +38,7 @@ func TestUserStore(t *testing.T, ss store.Store, s SqlSupplier) { t.Run("AnalyticsActiveCount", func(t *testing.T) { testUserStoreAnalyticsActiveCount(t, ss, s) }) t.Run("AnalyticsGetInactiveUsersCount", func(t *testing.T) { testUserStoreAnalyticsGetInactiveUsersCount(t, ss) }) t.Run("AnalyticsGetSystemAdminCount", func(t *testing.T) { testUserStoreAnalyticsGetSystemAdminCount(t, ss) }) + t.Run("AnalyticsGetGuestCount", func(t *testing.T) { testUserStoreAnalyticsGetGuestCount(t, ss) }) t.Run("Save", func(t *testing.T) { testUserStoreSave(t, ss) }) t.Run("Update", func(t *testing.T) { testUserStoreUpdate(t, ss) }) t.Run("UpdateUpdateAt", func(t *testing.T) { testUserStoreUpdateUpdateAt(t, ss) }) @@ -3162,6 +3163,42 @@ func testUserStoreAnalyticsGetSystemAdminCount(t *testing.T, ss store.Store) { } +func testUserStoreAnalyticsGetGuestCount(t *testing.T, ss store.Store) { + countBefore, err := ss.User().AnalyticsGetSystemAdminCount() + require.Nil(t, err) + + u1 := model.User{} + u1.Email = MakeEmail() + u1.Username = model.NewId() + u1.Roles = "system_user system_admin" + + u2 := model.User{} + u2.Email = MakeEmail() + u2.Username = model.NewId() + u2.Roles = "system_user" + + u3 := model.User{} + u3.Email = MakeEmail() + u3.Username = model.NewId() + u3.Roles = "system_guest" + + _, err = ss.User().Save(&u1) + require.Nil(t, err, "couldn't save user") + defer func() { require.Nil(t, ss.User().PermanentDelete(u1.Id)) }() + + _, err = ss.User().Save(&u2) + require.Nil(t, err, "couldn't save user") + defer func() { require.Nil(t, ss.User().PermanentDelete(u2.Id)) }() + + _, err = ss.User().Save(&u3) + require.Nil(t, err, "couldn't save user") + defer func() { require.Nil(t, ss.User().PermanentDelete(u3.Id)) }() + + result, err := ss.User().AnalyticsGetSystemAdminCount() + require.Nil(t, err) + require.Equal(t, countBefore+1, result, "Did not get the expected number of system admins.") +} + func testUserStoreGetProfilesNotInTeam(t *testing.T, ss store.Store) { team, err := ss.Team().Save(&model.Team{ DisplayName: "Team", diff --git a/store/timer_layer.go b/store/timer_layer.go index e55f1239c0..e50ddd3fdd 100644 --- a/store/timer_layer.go +++ b/store/timer_layer.go @@ -1489,6 +1489,22 @@ func (s *TimerLayerChannelStore) RemoveMember(channelId string, userId string) * return resultVar0 } +func (s *TimerLayerChannelStore) RemoveMembers(channelId string, userIds []string) *model.AppError { + start := timemodule.Now() + + resultVar0 := s.ChannelStore.RemoveMembers(channelId, userIds) + + elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second) + if s.Root.Metrics != nil { + success := "false" + if resultVar0 == nil { + success = "true" + } + s.Root.Metrics.ObserveStoreMethodDuration("ChannelStore.RemoveMembers", success, elapsed) + } + return resultVar0 +} + func (s *TimerLayerChannelStore) ResetAllChannelSchemes() *model.AppError { start := timemodule.Now() @@ -4924,6 +4940,38 @@ func (s *TimerLayerRoleStore) Save(role *model.Role) (*model.Role, *model.AppErr return resultVar0, resultVar1 } +func (s *TimerLayerSchemeStore) CountByScope(scope string) (int64, *model.AppError) { + start := timemodule.Now() + + resultVar0, resultVar1 := s.SchemeStore.CountByScope(scope) + + elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second) + if s.Root.Metrics != nil { + success := "false" + if resultVar1 == nil { + success = "true" + } + s.Root.Metrics.ObserveStoreMethodDuration("SchemeStore.CountByScope", success, elapsed) + } + return resultVar0, resultVar1 +} + +func (s *TimerLayerSchemeStore) CountWithoutPermission(scope string, permissionID string, roleScope model.RoleScope, roleType model.RoleType) (int64, *model.AppError) { + start := timemodule.Now() + + resultVar0, resultVar1 := s.SchemeStore.CountWithoutPermission(scope, permissionID, roleScope, roleType) + + elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second) + if s.Root.Metrics != nil { + success := "false" + if resultVar1 == nil { + success = "true" + } + s.Root.Metrics.ObserveStoreMethodDuration("SchemeStore.CountWithoutPermission", success, elapsed) + } + return resultVar0, resultVar1 +} + func (s *TimerLayerSchemeStore) Delete(schemeId string) (*model.Scheme, *model.AppError) { start := timemodule.Now() @@ -6025,6 +6073,22 @@ func (s *TimerLayerTeamStore) RemoveMember(teamId string, userId string) *model. return resultVar0 } +func (s *TimerLayerTeamStore) RemoveMembers(teamId string, userIds []string) *model.AppError { + start := timemodule.Now() + + resultVar0 := s.TeamStore.RemoveMembers(teamId, userIds) + + elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second) + if s.Root.Metrics != nil { + success := "false" + if resultVar0 == nil { + success = "true" + } + s.Root.Metrics.ObserveStoreMethodDuration("TeamStore.RemoveMembers", success, elapsed) + } + return resultVar0 +} + func (s *TimerLayerTeamStore) ResetAllTeamSchemes() *model.AppError { start := timemodule.Now() @@ -6392,6 +6456,22 @@ func (s *TimerLayerUserStore) AnalyticsActiveCount(time int64, options model.Use return resultVar0, resultVar1 } +func (s *TimerLayerUserStore) AnalyticsGetGuestCount() (int64, *model.AppError) { + start := timemodule.Now() + + resultVar0, resultVar1 := s.UserStore.AnalyticsGetGuestCount() + + elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second) + if s.Root.Metrics != nil { + success := "false" + if resultVar1 == nil { + success = "true" + } + s.Root.Metrics.ObserveStoreMethodDuration("UserStore.AnalyticsGetGuestCount", success, elapsed) + } + return resultVar0, resultVar1 +} + func (s *TimerLayerUserStore) AnalyticsGetInactiveUsersCount() (int64, *model.AppError) { start := timemodule.Now()