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