From b0d74c4e40396a77471c00c57c80da50997b18f5 Mon Sep 17 00:00:00 2001 From: Farhan Munshi <3207297+fmunshi@users.noreply.github.com> Date: Fri, 22 May 2020 10:56:15 -0400 Subject: [PATCH] [MM-25385] Add group_count_with_allow_reference telemetry (#14614) * MM-25385 Add group_count_with_allow_reference telemetry * Add store layers * Fix tests * Fix linting --- app/diagnostics.go | 20 +++++++++++------ store/opentracing_layer.go | 18 ++++++++++++++++ store/sqlstore/group_store.go | 16 ++++++++++---- store/store.go | 3 +++ store/storetest/group_store.go | 33 +++++++++++++++++++++++++++++ store/storetest/mocks/GroupStore.go | 23 ++++++++++++++++++++ store/timer_layer.go | 16 ++++++++++++++ 7 files changed, 118 insertions(+), 11 deletions(-) diff --git a/app/diagnostics.go b/app/diagnostics.go index 35e411b898..24ec6aff31 100644 --- a/app/diagnostics.go +++ b/app/diagnostics.go @@ -1018,14 +1018,20 @@ func (a *App) trackGroups() { mlog.Error(err.Error()) } + groupCountWithAllowReference, err := a.Srv().Store.Group().GroupCountWithAllowReference() + if err != nil { + mlog.Error(err.Error()) + } + a.SendDiagnostic(TRACK_GROUPS, map[string]interface{}{ - "group_count": groupCount, - "group_team_count": groupTeamCount, - "group_channel_count": groupChannelCount, - "group_synced_team_count": groupSyncedTeamCount, - "group_synced_channel_count": groupSyncedChannelCount, - "group_member_count": groupMemberCount, - "distinct_group_member_count": distinctGroupMemberCount, + "group_count": groupCount, + "group_team_count": groupTeamCount, + "group_channel_count": groupChannelCount, + "group_synced_team_count": groupSyncedTeamCount, + "group_synced_channel_count": groupSyncedChannelCount, + "group_member_count": groupMemberCount, + "distinct_group_member_count": distinctGroupMemberCount, + "group_count_with_allow_reference": groupCountWithAllowReference, }) } diff --git a/store/opentracing_layer.go b/store/opentracing_layer.go index dc1d6bacee..9523ad7984 100644 --- a/store/opentracing_layer.go +++ b/store/opentracing_layer.go @@ -3450,6 +3450,24 @@ func (s *OpenTracingLayerGroupStore) GroupCount() (int64, *model.AppError) { return resultVar0, resultVar1 } +func (s *OpenTracingLayerGroupStore) GroupCountWithAllowReference() (int64, *model.AppError) { + origCtx := s.Root.Store.Context() + span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "GroupStore.GroupCountWithAllowReference") + s.Root.Store.SetContext(newCtx) + defer func() { + s.Root.Store.SetContext(origCtx) + }() + + defer span.Finish() + resultVar0, resultVar1 := s.GroupStore.GroupCountWithAllowReference() + if resultVar1 != nil { + span.LogFields(spanlog.Error(resultVar1)) + ext.Error.Set(span, true) + } + + return resultVar0, resultVar1 +} + func (s *OpenTracingLayerGroupStore) GroupMemberCount() (int64, *model.AppError) { origCtx := s.Root.Store.Context() span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "GroupStore.GroupMemberCount") diff --git a/store/sqlstore/group_store.go b/store/sqlstore/group_store.go index 008e5bf99c..89f30e2a08 100644 --- a/store/sqlstore/group_store.go +++ b/store/sqlstore/group_store.go @@ -1443,15 +1443,23 @@ func (s *SqlGroupStore) GroupMemberCount() (int64, *model.AppError) { } func (s *SqlGroupStore) DistinctGroupMemberCount() (int64, *model.AppError) { - return s.countTableWithSelect("COUNT(DISTINCT UserId)", "GroupMembers") + return s.countTableWithSelectAndWhere("COUNT(DISTINCT UserId)", "GroupMembers", nil) +} + +func (s *SqlGroupStore) GroupCountWithAllowReference() (int64, *model.AppError) { + return s.countTableWithSelectAndWhere("COUNT(*)", "UserGroups", sq.Eq{"AllowReference": true, "DeleteAt": 0}) } func (s *SqlGroupStore) countTable(tableName string) (int64, *model.AppError) { - return s.countTableWithSelect("COUNT(*)", tableName) + return s.countTableWithSelectAndWhere("COUNT(*)", tableName, nil) } -func (s *SqlGroupStore) countTableWithSelect(selectStr, tableName string) (int64, *model.AppError) { - query := s.getQueryBuilder().Select(selectStr).From(tableName).Where(sq.Eq{"DeleteAt": 0}) +func (s *SqlGroupStore) countTableWithSelectAndWhere(selectStr, tableName string, whereStmt map[string]interface{}) (int64, *model.AppError) { + if whereStmt == nil { + whereStmt = sq.Eq{"DeleteAt": 0} + } + + query := s.getQueryBuilder().Select(selectStr).From(tableName).Where(whereStmt) sql, args, err := query.ToSql() if err != nil { diff --git a/store/store.go b/store/store.go index ef66dc4a4a..5fd3ece1b6 100644 --- a/store/store.go +++ b/store/store.go @@ -703,6 +703,9 @@ type GroupStore interface { // DistinctGroupMemberCount returns the count of records in the GroupMembers table with distinct UserId values. DistinctGroupMemberCount() (int64, *model.AppError) + + // GroupCountWithAllowReference returns the count of records in the Groups table with AllowReference set to true. + GroupCountWithAllowReference() (int64, *model.AppError) } type LinkMetadataStore interface { diff --git a/store/storetest/group_store.go b/store/storetest/group_store.go index 58a3ce0c6e..add3447f08 100644 --- a/store/storetest/group_store.go +++ b/store/storetest/group_store.go @@ -81,6 +81,7 @@ func TestGroupStore(t *testing.T, ss store.Store) { t.Run("GroupChannelCount", func(t *testing.T) { groupTestGroupChannelCount(t, ss) }) t.Run("GroupMemberCount", func(t *testing.T) { groupTestGroupMemberCount(t, ss) }) t.Run("DistinctGroupMemberCount", func(t *testing.T) { groupTestDistinctGroupMemberCount(t, ss) }) + t.Run("GroupCountWithAllowReference", func(t *testing.T) { groupTestGroupCountWithAllowReference(t, ss) }) } func testGroupStoreCreate(t *testing.T, ss store.Store) { @@ -4514,3 +4515,35 @@ func groupTestDistinctGroupMemberCount(t *testing.T, ss store.Store) { require.Nil(t, err) require.GreaterOrEqual(t, countAfter2, countAfter1) } + +func groupTestGroupCountWithAllowReference(t *testing.T, ss store.Store) { + initialCount, err := ss.Group().GroupCountWithAllowReference() + require.Nil(t, err) + + group1, err := ss.Group().Create(&model.Group{ + Name: model.NewId(), + DisplayName: model.NewId(), + Source: model.GroupSourceLdap, + RemoteId: model.NewId(), + }) + require.Nil(t, err) + defer ss.Group().Delete(group1.Id) + + count, err := ss.Group().GroupCountWithAllowReference() + require.Nil(t, err) + require.Equal(t, count, initialCount) + + group2, err := ss.Group().Create(&model.Group{ + Name: model.NewId(), + DisplayName: model.NewId(), + Source: model.GroupSourceLdap, + RemoteId: model.NewId(), + AllowReference: true, + }) + require.Nil(t, err) + defer ss.Group().Delete(group2.Id) + + countAfter, err := ss.Group().GroupCountWithAllowReference() + require.Nil(t, err) + require.Greater(t, countAfter, count) +} diff --git a/store/storetest/mocks/GroupStore.go b/store/storetest/mocks/GroupStore.go index a329116a90..3361f0f77c 100644 --- a/store/storetest/mocks/GroupStore.go +++ b/store/storetest/mocks/GroupStore.go @@ -869,6 +869,29 @@ func (_m *GroupStore) GroupTeamCount() (int64, *model.AppError) { return r0, r1 } +// GroupCountWithAllowReference provides a mock function with given fields: +func (_m *GroupStore) GroupCountWithAllowReference() (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 +} + // PermanentDeleteMembersByUser provides a mock function with given fields: userId func (_m *GroupStore) PermanentDeleteMembersByUser(userId string) *model.AppError { ret := _m.Called(userId) diff --git a/store/timer_layer.go b/store/timer_layer.go index d900daa599..46aed5b8d1 100644 --- a/store/timer_layer.go +++ b/store/timer_layer.go @@ -3150,6 +3150,22 @@ func (s *TimerLayerGroupStore) GroupCount() (int64, *model.AppError) { return resultVar0, resultVar1 } +func (s *TimerLayerGroupStore) GroupCountWithAllowReference() (int64, *model.AppError) { + start := timemodule.Now() + + resultVar0, resultVar1 := s.GroupStore.GroupCountWithAllowReference() + + elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second) + if s.Root.Metrics != nil { + success := "false" + if resultVar1 == nil { + success = "true" + } + s.Root.Metrics.ObserveStoreMethodDuration("GroupStore.GroupCountWithAllowReference", success, elapsed) + } + return resultVar0, resultVar1 +} + func (s *TimerLayerGroupStore) GroupMemberCount() (int64, *model.AppError) { start := timemodule.Now()