From d3878ecd623e0f0b408b7be0edbf904883905893 Mon Sep 17 00:00:00 2001 From: Mihai Parparita Date: Tue, 15 Nov 2022 14:41:36 -0800 Subject: [PATCH] ipn/ipnlocal: add client metrics for profile switching Updates #713 Signed-off-by: Mihai Parparita --- ipn/ipnlocal/profiles.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/ipn/ipnlocal/profiles.go b/ipn/ipnlocal/profiles.go index 1180b07c5..1fe6ab1ed 100644 --- a/ipn/ipnlocal/profiles.go +++ b/ipn/ipnlocal/profiles.go @@ -15,6 +15,7 @@ "golang.org/x/exp/slices" "tailscale.com/ipn" "tailscale.com/types/logger" + "tailscale.com/util/clientmetric" "tailscale.com/util/strs" "tailscale.com/version" ) @@ -201,6 +202,8 @@ func (pm *profileManager) Profiles() []ipn.LoginProfile { // SwitchProfile switches to the profile with the given id. // If the profile is not known, it returns an errProfileNotFound. func (pm *profileManager) SwitchProfile(id ipn.ProfileID) error { + metricSwitchProfile.Add(1) + kp, ok := pm.knownProfiles[id] if !ok { return errProfileNotFound @@ -268,6 +271,8 @@ func (pm *profileManager) CurrentProfile() ipn.LoginProfile { // useful for deleting the last profile. In other cases, it is // recommended to call SwitchProfile() first. func (pm *profileManager) DeleteProfile(id ipn.ProfileID) error { + metricDeleteProfile.Add(1) + if id == "" && pm.isNewProfile { // Deleting the in-memory only new profile, just create a new one. pm.NewProfile() @@ -298,6 +303,8 @@ func (pm *profileManager) writeKnownProfiles() error { // NewProfile creates and switches to a new unnamed profile. The new profile is // not persisted until SetPrefs is called with a logged-in user. func (pm *profileManager) NewProfile() { + metricNewProfile.Add(1) + pm.prefs = emptyPrefs pm.isNewProfile = true pm.currentProfile = &ipn.LoginProfile{} @@ -420,6 +427,7 @@ func newProfileManagerWithGOOS(store ipn.StateStore, logf logger.Logf, stateKey } func (pm *profileManager) migrateFromLegacyPrefs() error { + metricMigration.Add(1) pm.NewProfile() k := ipn.LegacyGlobalDaemonStateKey switch { @@ -432,13 +440,26 @@ func (pm *profileManager) migrateFromLegacyPrefs() error { } prefs, err := pm.loadSavedPrefs(k) if err != nil { + metricMigrationError.Add(1) return fmt.Errorf("calling ReadState on state store: %w", err) } pm.logf("migrating %q profile to new format", k) if err := pm.SetPrefs(prefs); err != nil { + metricMigrationError.Add(1) return fmt.Errorf("migrating _daemon profile: %w", err) } // Do not delete the old state key, as we may be downgraded to an // older version that still relies on it. + metricMigrationSuccess.Add(1) return nil } + +var ( + metricNewProfile = clientmetric.NewCounter("profiles_new") + metricSwitchProfile = clientmetric.NewCounter("profiles_switch") + metricDeleteProfile = clientmetric.NewCounter("profiles_delete") + + metricMigration = clientmetric.NewCounter("profiles_migration") + metricMigrationError = clientmetric.NewCounter("profiles_migration_error") + metricMigrationSuccess = clientmetric.NewCounter("profiles_migration_success") +)