diff --git a/conf/defaults.ini b/conf/defaults.ini index 224555260f2..f9e230c580e 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -519,6 +519,9 @@ user_invite_max_lifetime_duration = 24h # The duration in time a verification email, used to update the email address of a user, remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 1h (1 hour). verification_email_max_lifetime_duration = 1h +# Frequency of updating a user's last seen time. The minimum supported duration is 5m (5 minutes). The maximum supported duration is 1h (1 hour) +last_seen_update_interval = 15m + # Enter a comma-separated list of usernames to hide them in the Grafana UI. These users are shown to Grafana admins and to themselves. hidden_users = diff --git a/conf/sample.ini b/conf/sample.ini index edd415de28b..5257c046add 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -520,6 +520,9 @@ # The duration in time a verification email, used to update the email address of a user, remains valid before expiring. This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 1h (1 hour). ;verification_email_max_lifetime_duration = 1h +# Frequency of updating a user's last seen time. The minimum supported duration is 5m (5 minutes). The maximum supported duration is 1h (1 hour). +;last_seen_update_interval = 15m + # Enter a comma-separated list of users login to hide them in the Grafana UI. These users are shown to Grafana admins and themselves. ; hidden_users = diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md index 1527fd91830..bf95f825a07 100644 --- a/docs/sources/setup-grafana/configure-grafana/_index.md +++ b/docs/sources/setup-grafana/configure-grafana/_index.md @@ -892,6 +892,12 @@ The duration in time a verification email, used to update the email address of a This setting should be expressed as a duration. Examples: 6h (hours), 2d (days), 1w (week). Default is 1h (1 hour). +### last_seen_update_interval + +The frequency of updating a user's last seen time. +This setting should be expressed as a duration. Examples: 1h (hour), 15m (minutes) +Default is `15m` (15 minutes). The minimum supported duration is `5m` (5 minutes). The maximum supported duration is `1h` (1 hour). + ### hidden_users This is a comma-separated list of usernames. Users specified here are hidden in the Grafana UI. They are still visible to Grafana administrators and to themselves. diff --git a/pkg/services/user/userimpl/user.go b/pkg/services/user/userimpl/user.go index e7168251986..3e340736498 100644 --- a/pkg/services/user/userimpl/user.go +++ b/pkg/services/user/userimpl/user.go @@ -301,15 +301,15 @@ func (s *Service) UpdateLastSeenAt(ctx context.Context, cmd *user.UpdateUserLast return err } - if !shouldUpdateLastSeen(u.LastSeenAt) { + if !s.shouldUpdateLastSeen(u.LastSeenAt) { return user.ErrLastSeenUpToDate } return s.store.UpdateLastSeenAt(ctx, cmd) } -func shouldUpdateLastSeen(t time.Time) bool { - return time.Since(t) > time.Minute*15 +func (s *Service) shouldUpdateLastSeen(t time.Time) bool { + return time.Since(t) > s.cfg.UserLastSeenUpdateInterval } func (s *Service) GetSignedInUser(ctx context.Context, query *user.GetSignedInUserQuery) (*user.SignedInUser, error) { diff --git a/pkg/services/user/userimpl/user_test.go b/pkg/services/user/userimpl/user_test.go index 346f8545267..da30c586564 100644 --- a/pkg/services/user/userimpl/user_test.go +++ b/pkg/services/user/userimpl/user_test.go @@ -221,6 +221,7 @@ func TestUpdateLastSeenAt(t *testing.T) { tracer: tracing.InitializeTracerForTest(), } userService.cfg = setting.NewCfg() + userService.cfg.UserLastSeenUpdateInterval = 5 * time.Minute t.Run("update last seen at", func(t *testing.T) { userStore.ExpectedSignedInUser = &user.SignedInUser{UserID: 1, OrgID: 1, Email: "email", Login: "login", Name: "name", LastSeenAt: time.Now().Add(-20 * time.Minute)} diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index ab0688afd66..336a27b7e28 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -306,6 +306,7 @@ type Cfg struct { UserInviteMaxLifetime time.Duration HiddenUsers map[string]struct{} CaseInsensitiveLogin bool // Login and Email will be considered case insensitive + UserLastSeenUpdateInterval time.Duration VerificationEmailMaxLifetime time.Duration // Service Accounts @@ -1695,6 +1696,19 @@ func readUserSettings(iniFile *ini.File, cfg *Cfg) error { return errors.New("the minimum supported value for the `user_invite_max_lifetime_duration` configuration is 15m (15 minutes)") } + cfg.UserLastSeenUpdateInterval, err = gtime.ParseDuration(valueAsString(users, "last_seen_update_interval", "15m")) + if err != nil { + return err + } + + if cfg.UserLastSeenUpdateInterval < time.Minute*5 { + cfg.Logger.Warn("the minimum supported value for the `last_seen_update_interval` configuration is 5m (5 minutes)") + cfg.UserLastSeenUpdateInterval = time.Minute * 5 + } else if cfg.UserLastSeenUpdateInterval > time.Hour*1 { + cfg.Logger.Warn("the maximum supported value for the `last_seen_update_interval` configuration is 1h (1 hour)") + cfg.UserLastSeenUpdateInterval = time.Hour * 1 + } + cfg.HiddenUsers = make(map[string]struct{}) hiddenUsers := users.Key("hidden_users").MustString("") for _, user := range strings.Split(hiddenUsers, ",") {