MM-23093 Implement Server Setup telemetry - server configuration (#14374)
* added advanced first day diagnostics reporting * typo * config corrected * defaults * moved from config to system db table * missing file * added error handling * tests * typos Co-authored-by: mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
278c295869
Коммит
7800116429
12
app/app.go
12
app/app.go
@@ -142,6 +142,18 @@ func (a *App) getSystemInstallDate() (int64, *model.AppError) {
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (a *App) getFirstServerRunTimestamp() (int64, *model.AppError) {
|
||||
systemData, appErr := a.Srv().Store.System().GetByName(model.SYSTEM_FIRST_SERVER_RUN_TIMESTAMP_KEY)
|
||||
if appErr != nil {
|
||||
return 0, appErr
|
||||
}
|
||||
value, err := strconv.ParseInt(systemData.Value, 10, 64)
|
||||
if err != nil {
|
||||
return 0, model.NewAppError("getFirstServerRunTimestamp", "app.system_install_date.parse_int.app_error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (a *App) Srv() *Server {
|
||||
return a.srv
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ func TestUnitUpdateConfig(t *testing.T) {
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
mockStore.On("User").Return(&mockUserStore)
|
||||
mockStore.On("Post").Return(&mockPostStore)
|
||||
mockStore.On("System").Return(&mockSystemStore)
|
||||
|
||||
@@ -265,6 +265,22 @@ func (a *App) ensureInstallationDate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) ensureFirstServerRunTimestamp() error {
|
||||
_, err := a.getFirstServerRunTimestamp()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = a.Srv().Store.System().SaveOrUpdate(&model.System{
|
||||
Name: model.SYSTEM_FIRST_SERVER_RUN_TIMESTAMP_KEY,
|
||||
Value: strconv.FormatInt(utils.MillisFromTime(time.Now()), 10),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AsymmetricSigningKey will return a private key that can be used for asymmetric signing.
|
||||
func (s *Server) AsymmetricSigningKey() *ecdsa.PrivateKey {
|
||||
return s.asymmetricSigningKey
|
||||
|
||||
@@ -105,6 +105,8 @@ func TestSAMLSettings(t *testing.T) {
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := storemocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
mockStore.On("User").Return(&mockUserStore)
|
||||
mockStore.On("Post").Return(&mockPostStore)
|
||||
mockStore.On("System").Return(&mockSystemStore)
|
||||
|
||||
@@ -555,6 +555,8 @@ func TestGetPushNotificationMessage(t *testing.T) {
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
mockStore.On("User").Return(&mockUserStore)
|
||||
mockStore.On("Post").Return(&mockPostStore)
|
||||
mockStore.On("System").Return(&mockSystemStore)
|
||||
@@ -1125,6 +1127,8 @@ func TestClearPushNotificationSync(t *testing.T) {
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
mockSessionStore := mocks.SessionStore{}
|
||||
mockSessionStore.On("GetSessionsWithActiveDeviceIds", mock.AnythingOfType("string")).Return([]*model.Session{sess1, sess2}, nil)
|
||||
mockSessionStore.On("UpdateDeviceId", mock.AnythingOfType("string"), mock.AnythingOfType("string"), mock.AnythingOfType("int64")).Return("testdeviceID", nil)
|
||||
@@ -1177,6 +1181,8 @@ func TestUpdateMobileAppBadgeSync(t *testing.T) {
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
mockSessionStore := mocks.SessionStore{}
|
||||
mockSessionStore.On("GetSessionsWithActiveDeviceIds", mock.AnythingOfType("string")).Return([]*model.Session{sess1, sess2}, nil)
|
||||
mockSessionStore.On("UpdateDeviceId", mock.AnythingOfType("string"), mock.AnythingOfType("string"), mock.AnythingOfType("int64")).Return("testdeviceID", nil)
|
||||
@@ -1217,6 +1223,8 @@ func TestSendAckToPushProxy(t *testing.T) {
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
mockStore.On("User").Return(&mockUserStore)
|
||||
mockStore.On("Post").Return(&mockPostStore)
|
||||
mockStore.On("System").Return(&mockSystemStore)
|
||||
@@ -1371,6 +1379,8 @@ func BenchmarkPushNotificationThroughput(b *testing.B) {
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
mockSessionStore := mocks.SessionStore{}
|
||||
mockPreferenceStore := mocks.PreferenceStore{}
|
||||
mockPreferenceStore.On("Get", mock.AnythingOfType("string"), mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(&model.Preference{Value: "test"}, nil)
|
||||
|
||||
@@ -27,6 +27,8 @@ func TestPluginPublicKeys(t *testing.T) {
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := mocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
mockStore.On("User").Return(&mockUserStore)
|
||||
mockStore.On("Post").Return(&mockPostStore)
|
||||
mockStore.On("System").Return(&mockSystemStore)
|
||||
|
||||
@@ -460,6 +460,8 @@ func TestImageProxy(t *testing.T) {
|
||||
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
|
||||
mockSystemStore := storemocks.SystemStore{}
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
|
||||
mockStore.On("User").Return(&mockUserStore)
|
||||
mockStore.On("Post").Return(&mockPostStore)
|
||||
mockStore.On("System").Return(&mockSystemStore)
|
||||
|
||||
@@ -146,7 +146,8 @@ type Server struct {
|
||||
|
||||
CacheProvider cache.Provider
|
||||
|
||||
tracer *tracing.Tracer
|
||||
tracer *tracing.Tracer
|
||||
timestampLastDiagnosticSent time.Time
|
||||
}
|
||||
|
||||
func NewServer(options ...Option) (*Server, error) {
|
||||
@@ -727,11 +728,32 @@ func runSecurityJob(s *Server) {
|
||||
}, time.Hour*4)
|
||||
}
|
||||
|
||||
func runDiagnosticsJob(s *Server) {
|
||||
doDiagnostics(s)
|
||||
model.CreateRecurringTask("Diagnostics", func() {
|
||||
func doDiagnosticsIfNeeded(s *Server, firstRun time.Time) {
|
||||
hoursSinceFirstServerRun := time.Since(firstRun).Hours()
|
||||
// Send once every 10 minutes for the first hour
|
||||
// Send once every hour thereafter for the first 12 hours
|
||||
// Send at the 24 hour mark and every 24 hours after
|
||||
if hoursSinceFirstServerRun < 1 {
|
||||
doDiagnostics(s)
|
||||
}, time.Hour*24)
|
||||
} else if hoursSinceFirstServerRun <= 12 && time.Since(s.timestampLastDiagnosticSent) >= time.Hour {
|
||||
doDiagnostics(s)
|
||||
} else if hoursSinceFirstServerRun > 12 && time.Since(s.timestampLastDiagnosticSent) >= 24*time.Hour {
|
||||
doDiagnostics(s)
|
||||
}
|
||||
}
|
||||
|
||||
func runDiagnosticsJob(s *Server) {
|
||||
// Send on boot
|
||||
doDiagnostics(s)
|
||||
firstRun, err := s.FakeApp().getFirstServerRunTimestamp()
|
||||
if err != nil {
|
||||
mlog.Warn("Fetching time of first server run failed. Setting to 'now'.")
|
||||
s.FakeApp().ensureFirstServerRunTimestamp()
|
||||
firstRun = utils.MillisFromTime(time.Now())
|
||||
}
|
||||
model.CreateRecurringTask("Diagnostics", func() {
|
||||
doDiagnosticsIfNeeded(s, utils.TimeFromMillis(firstRun))
|
||||
}, time.Minute*10)
|
||||
}
|
||||
|
||||
func runTokenCleanupJob(s *Server) {
|
||||
@@ -761,6 +783,7 @@ func doSecurity(s *Server) {
|
||||
|
||||
func doDiagnostics(s *Server) {
|
||||
if *s.Config().LogSettings.EnableDiagnostics {
|
||||
s.timestampLastDiagnosticSent = time.Now()
|
||||
s.FakeApp().SendDailyDiagnostics()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,10 @@ func (s *Server) RunOldAppInitialization() error {
|
||||
return errors.Wrapf(err, "unable to ensure installation date")
|
||||
}
|
||||
|
||||
if err := s.FakeApp().ensureFirstServerRunTimestamp(); err != nil {
|
||||
return errors.Wrapf(err, "unable to ensure first run timestamp")
|
||||
}
|
||||
|
||||
s.ensureDiagnosticId()
|
||||
s.FakeApp().regenerateClientConfig()
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user