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