github.com/lologarithm/mattermost-server@v5.3.2-0.20181002060438-c82a84ed765b+incompatible/app/analytics.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "fmt" 8 9 "github.com/mattermost/mattermost-server/mlog" 10 "github.com/mattermost/mattermost-server/model" 11 "github.com/mattermost/mattermost-server/store" 12 ) 13 14 const ( 15 DAY_MILLISECONDS = 24 * 60 * 60 * 1000 16 MONTH_MILLISECONDS = 31 * DAY_MILLISECONDS 17 ) 18 19 func (a *App) GetAnalytics(name string, teamId string) (model.AnalyticsRows, *model.AppError) { 20 skipIntensiveQueries := false 21 var systemUserCount int64 22 r := <-a.Srv.Store.User().AnalyticsUniqueUserCount("") 23 if r.Err != nil { 24 return nil, r.Err 25 } 26 27 systemUserCount = r.Data.(int64) 28 if systemUserCount > int64(*a.Config().AnalyticsSettings.MaxUsersForStatistics) { 29 mlog.Debug(fmt.Sprintf("More than %v users on the system, intensive queries skipped", *a.Config().AnalyticsSettings.MaxUsersForStatistics)) 30 skipIntensiveQueries = true 31 } 32 33 if name == "standard" { 34 var rows model.AnalyticsRows = make([]*model.AnalyticsRow, 11) 35 rows[0] = &model.AnalyticsRow{Name: "channel_open_count", Value: 0} 36 rows[1] = &model.AnalyticsRow{Name: "channel_private_count", Value: 0} 37 rows[2] = &model.AnalyticsRow{Name: "post_count", Value: 0} 38 rows[3] = &model.AnalyticsRow{Name: "unique_user_count", Value: 0} 39 rows[4] = &model.AnalyticsRow{Name: "team_count", Value: 0} 40 rows[5] = &model.AnalyticsRow{Name: "total_websocket_connections", Value: 0} 41 rows[6] = &model.AnalyticsRow{Name: "total_master_db_connections", Value: 0} 42 rows[7] = &model.AnalyticsRow{Name: "total_read_db_connections", Value: 0} 43 rows[8] = &model.AnalyticsRow{Name: "daily_active_users", Value: 0} 44 rows[9] = &model.AnalyticsRow{Name: "monthly_active_users", Value: 0} 45 rows[10] = &model.AnalyticsRow{Name: "inactive_user_count", Value: 0} 46 47 openChan := a.Srv.Store.Channel().AnalyticsTypeCount(teamId, model.CHANNEL_OPEN) 48 privateChan := a.Srv.Store.Channel().AnalyticsTypeCount(teamId, model.CHANNEL_PRIVATE) 49 teamChan := a.Srv.Store.Team().AnalyticsTeamCount() 50 51 var userChan store.StoreChannel 52 var userInactiveChan store.StoreChannel 53 if teamId == "" { 54 userInactiveChan = a.Srv.Store.User().AnalyticsGetInactiveUsersCount() 55 } else { 56 userChan = a.Srv.Store.User().AnalyticsUniqueUserCount(teamId) 57 } 58 59 var postChan store.StoreChannel 60 if !skipIntensiveQueries { 61 postChan = a.Srv.Store.Post().AnalyticsPostCount(teamId, false, false) 62 } 63 64 dailyActiveChan := a.Srv.Store.User().AnalyticsActiveCount(DAY_MILLISECONDS) 65 monthlyActiveChan := a.Srv.Store.User().AnalyticsActiveCount(MONTH_MILLISECONDS) 66 67 r := <-openChan 68 if r.Err != nil { 69 return nil, r.Err 70 } 71 rows[0].Value = float64(r.Data.(int64)) 72 73 r = <-privateChan 74 if r.Err != nil { 75 return nil, r.Err 76 } 77 rows[1].Value = float64(r.Data.(int64)) 78 79 if postChan == nil { 80 rows[2].Value = -1 81 } else { 82 r := <-postChan 83 if r.Err != nil { 84 return nil, r.Err 85 } 86 rows[2].Value = float64(r.Data.(int64)) 87 } 88 89 if userChan == nil { 90 rows[3].Value = float64(systemUserCount) 91 } else { 92 r := <-userChan 93 if r.Err != nil { 94 return nil, r.Err 95 } 96 rows[3].Value = float64(r.Data.(int64)) 97 } 98 99 if userInactiveChan == nil { 100 rows[10].Value = -1 101 } else { 102 r := <-userInactiveChan 103 if r.Err != nil { 104 return nil, r.Err 105 } 106 rows[10].Value = float64(r.Data.(int64)) 107 } 108 109 r = <-teamChan 110 if r.Err != nil { 111 return nil, r.Err 112 } 113 rows[4].Value = float64(r.Data.(int64)) 114 115 // If in HA mode then aggregrate all the stats 116 if a.Cluster != nil && *a.Config().ClusterSettings.Enable { 117 stats, err := a.Cluster.GetClusterStats() 118 if err != nil { 119 return nil, err 120 } 121 122 totalSockets := a.TotalWebsocketConnections() 123 totalMasterDb := a.Srv.Store.TotalMasterDbConnections() 124 totalReadDb := a.Srv.Store.TotalReadDbConnections() 125 126 for _, stat := range stats { 127 totalSockets = totalSockets + stat.TotalWebsocketConnections 128 totalMasterDb = totalMasterDb + stat.TotalMasterDbConnections 129 totalReadDb = totalReadDb + stat.TotalReadDbConnections 130 } 131 132 rows[5].Value = float64(totalSockets) 133 rows[6].Value = float64(totalMasterDb) 134 rows[7].Value = float64(totalReadDb) 135 136 } else { 137 rows[5].Value = float64(a.TotalWebsocketConnections()) 138 rows[6].Value = float64(a.Srv.Store.TotalMasterDbConnections()) 139 rows[7].Value = float64(a.Srv.Store.TotalReadDbConnections()) 140 } 141 142 r = <-dailyActiveChan 143 if r.Err != nil { 144 return nil, r.Err 145 } 146 rows[8].Value = float64(r.Data.(int64)) 147 148 r = <-monthlyActiveChan 149 if r.Err != nil { 150 return nil, r.Err 151 } 152 rows[9].Value = float64(r.Data.(int64)) 153 154 return rows, nil 155 } else if name == "post_counts_day" { 156 if skipIntensiveQueries { 157 rows := model.AnalyticsRows{&model.AnalyticsRow{Name: "", Value: -1}} 158 return rows, nil 159 } 160 161 r := <-a.Srv.Store.Post().AnalyticsPostCountsByDay(teamId) 162 if r.Err != nil { 163 return nil, r.Err 164 } 165 return r.Data.(model.AnalyticsRows), nil 166 } else if name == "user_counts_with_posts_day" { 167 if skipIntensiveQueries { 168 rows := model.AnalyticsRows{&model.AnalyticsRow{Name: "", Value: -1}} 169 return rows, nil 170 } 171 172 r := <-a.Srv.Store.Post().AnalyticsUserCountsWithPostsByDay(teamId) 173 if r.Err != nil { 174 return nil, r.Err 175 } 176 return r.Data.(model.AnalyticsRows), nil 177 } else if name == "extra_counts" { 178 var rows model.AnalyticsRows = make([]*model.AnalyticsRow, 6) 179 rows[0] = &model.AnalyticsRow{Name: "file_post_count", Value: 0} 180 rows[1] = &model.AnalyticsRow{Name: "hashtag_post_count", Value: 0} 181 rows[2] = &model.AnalyticsRow{Name: "incoming_webhook_count", Value: 0} 182 rows[3] = &model.AnalyticsRow{Name: "outgoing_webhook_count", Value: 0} 183 rows[4] = &model.AnalyticsRow{Name: "command_count", Value: 0} 184 rows[5] = &model.AnalyticsRow{Name: "session_count", Value: 0} 185 186 iHookChan := a.Srv.Store.Webhook().AnalyticsIncomingCount(teamId) 187 oHookChan := a.Srv.Store.Webhook().AnalyticsOutgoingCount(teamId) 188 commandChan := a.Srv.Store.Command().AnalyticsCommandCount(teamId) 189 sessionChan := a.Srv.Store.Session().AnalyticsSessionCount() 190 191 var fileChan store.StoreChannel 192 var hashtagChan store.StoreChannel 193 if !skipIntensiveQueries { 194 fileChan = a.Srv.Store.Post().AnalyticsPostCount(teamId, true, false) 195 hashtagChan = a.Srv.Store.Post().AnalyticsPostCount(teamId, false, true) 196 } 197 198 if fileChan == nil { 199 rows[0].Value = -1 200 } else { 201 r := <-fileChan 202 if r.Err != nil { 203 return nil, r.Err 204 } 205 rows[0].Value = float64(r.Data.(int64)) 206 } 207 208 if hashtagChan == nil { 209 rows[1].Value = -1 210 } else { 211 r := <-hashtagChan 212 if r.Err != nil { 213 return nil, r.Err 214 } 215 rows[1].Value = float64(r.Data.(int64)) 216 } 217 218 r := <-iHookChan 219 if r.Err != nil { 220 return nil, r.Err 221 } 222 rows[2].Value = float64(r.Data.(int64)) 223 224 r = <-oHookChan 225 if r.Err != nil { 226 return nil, r.Err 227 } 228 rows[3].Value = float64(r.Data.(int64)) 229 230 r = <-commandChan 231 if r.Err != nil { 232 return nil, r.Err 233 } 234 rows[4].Value = float64(r.Data.(int64)) 235 236 r = <-sessionChan 237 if r.Err != nil { 238 return nil, r.Err 239 } 240 rows[5].Value = float64(r.Data.(int64)) 241 242 return rows, nil 243 } 244 245 return nil, nil 246 } 247 248 func (a *App) GetRecentlyActiveUsersForTeam(teamId string) (map[string]*model.User, *model.AppError) { 249 result := <-a.Srv.Store.User().GetRecentlyActiveUsersForTeam(teamId, 0, 100) 250 if result.Err != nil { 251 return nil, result.Err 252 } 253 254 users := result.Data.([]*model.User) 255 userMap := make(map[string]*model.User) 256 257 for _, user := range users { 258 userMap[user.Id] = user 259 } 260 261 return userMap, nil 262 } 263 264 func (a *App) GetRecentlyActiveUsersForTeamPage(teamId string, page, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { 265 var users []*model.User 266 result := <-a.Srv.Store.User().GetRecentlyActiveUsersForTeam(teamId, page*perPage, perPage) 267 if result.Err != nil { 268 return nil, result.Err 269 } 270 users = result.Data.([]*model.User) 271 272 return a.sanitizeProfiles(users, asAdmin), nil 273 } 274 275 func (a *App) GetNewUsersForTeamPage(teamId string, page, perPage int, asAdmin bool) ([]*model.User, *model.AppError) { 276 var users []*model.User 277 result := <-a.Srv.Store.User().GetNewUsersForTeam(teamId, page*perPage, perPage) 278 if result.Err != nil { 279 return nil, result.Err 280 } 281 users = result.Data.([]*model.User) 282 283 return a.sanitizeProfiles(users, asAdmin), nil 284 }