diff --git a/src/Identity/Core/src/SignInManagerMetrics.cs b/src/Identity/Core/src/SignInManagerMetrics.cs index cfd81642dbfd..f14c37edf042 100644 --- a/src/Identity/Core/src/SignInManagerMetrics.cs +++ b/src/Identity/Core/src/SignInManagerMetrics.cs @@ -14,8 +14,8 @@ internal sealed class SignInManagerMetrics : IDisposable public const string RememberTwoFactorCounterName = "aspnetcore.identity.sign_in.remember_two_factor"; public const string ForgetTwoFactorCounterName = "aspnetcore.identity.sign_in.forget_two_factor"; public const string CheckPasswordCounterName = "aspnetcore.identity.sign_in.check_password"; - public const string SignInUserPrincipalCounterName = "aspnetcore.identity.sign_in.sign_in_principal"; - public const string SignOutUserPrincipalCounterName = "aspnetcore.identity.sign_in.sign_out_principal"; + public const string SignInUserPrincipalCounterName = "aspnetcore.identity.sign_in.sign_in"; + public const string SignOutUserPrincipalCounterName = "aspnetcore.identity.sign_in.sign_out"; private readonly Meter _meter; private readonly Counter _authenticateCounter; @@ -29,12 +29,12 @@ public SignInManagerMetrics(IMeterFactory meterFactory) { _meter = meterFactory.Create(MeterName); - _authenticateCounter = _meter.CreateCounter(AuthenticateCounterName, "count", "The number of authenticate attempts. The authenticate counter is incremented by sign in methods such as PasswordSignInAsync and TwoFactorSignInAsync."); - _rememberTwoFactorClientCounter = _meter.CreateCounter(RememberTwoFactorCounterName, "count", "The number of two factor clients remembered."); - _forgetTwoFactorCounter = _meter.CreateCounter(ForgetTwoFactorCounterName, "count", "The number of two factor clients forgotten."); - _checkPasswordCounter = _meter.CreateCounter(CheckPasswordCounterName, "count", "The number of check password attempts. Checks that the account is in a state that can log in and that the password is valid using the UserManager.CheckPasswordAsync method."); - _signInUserPrincipalCounter = _meter.CreateCounter(SignInUserPrincipalCounterName, "count", "The number of calls to sign in user principals."); - _signOutUserPrincipalCounter = _meter.CreateCounter(SignOutUserPrincipalCounterName, "count", "The number of calls to sign out user principals."); + _authenticateCounter = _meter.CreateCounter(AuthenticateCounterName, "{count}", "The number of authenticate attempts. The authenticate counter is incremented by sign in methods such as PasswordSignInAsync and TwoFactorSignInAsync."); + _rememberTwoFactorClientCounter = _meter.CreateCounter(RememberTwoFactorCounterName, "{count}", "The number of two factor clients remembered."); + _forgetTwoFactorCounter = _meter.CreateCounter(ForgetTwoFactorCounterName, "{count}", "The number of two factor clients forgotten."); + _checkPasswordCounter = _meter.CreateCounter(CheckPasswordCounterName, "{check}", "The number of check password attempts. Checks that the account is in a state that can log in and that the password is valid using the UserManager.CheckPasswordAsync method."); + _signInUserPrincipalCounter = _meter.CreateCounter(SignInUserPrincipalCounterName, "{sign_in}", "The number of calls to sign in user principals."); + _signOutUserPrincipalCounter = _meter.CreateCounter(SignOutUserPrincipalCounterName, "{sign_out}", "The number of calls to sign out user principals."); } internal void CheckPasswordSignIn(string userType, SignInResult? result, Exception? exception = null) @@ -49,7 +49,7 @@ internal void CheckPasswordSignIn(string userType, SignInResult? result, Excepti { "aspnetcore.identity.user_type", userType }, }; AddSignInResult(ref tags, result); - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception); _checkPasswordCounter.Add(1, tags); } @@ -69,7 +69,7 @@ internal void AuthenticateSignIn(string userType, string authenticationScheme, S }; AddIsPersistent(ref tags, isPersistent); AddSignInResult(ref tags, result); - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception); _authenticateCounter.Add(1, tags); } @@ -87,7 +87,7 @@ internal void SignInUserPrincipal(string userType, string authenticationScheme, { "aspnetcore.identity.authentication_scheme", authenticationScheme }, }; AddIsPersistent(ref tags, isPersistent); - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception); _signInUserPrincipalCounter.Add(1, tags); } @@ -104,7 +104,7 @@ internal void SignOutUserPrincipal(string userType, string authenticationScheme, { "aspnetcore.identity.user_type", userType }, { "aspnetcore.identity.authentication_scheme", authenticationScheme }, }; - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception); _signOutUserPrincipalCounter.Add(1, tags); } @@ -121,7 +121,7 @@ internal void RememberTwoFactorClient(string userType, string authenticationSche { "aspnetcore.identity.user_type", userType }, { "aspnetcore.identity.authentication_scheme", authenticationScheme } }; - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception); _rememberTwoFactorClientCounter.Add(1, tags); } @@ -138,7 +138,7 @@ internal void ForgetTwoFactorClient(string userType, string authenticationScheme { "aspnetcore.identity.user_type", userType }, { "aspnetcore.identity.authentication_scheme", authenticationScheme } }; - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception); _forgetTwoFactorCounter.Add(1, tags); } @@ -164,7 +164,7 @@ private static void AddSignInResult(ref TagList tags, SignInResult? result) } } - private static void AddExceptionTags(ref TagList tags, Exception? exception) + private static void AddErrorTag(ref TagList tags, Exception? exception) { if (exception != null) { @@ -182,7 +182,7 @@ private static string GetSignInType(SignInType signInType) SignInType.TwoFactor => "two_factor", SignInType.External => "external", SignInType.Passkey => "passkey", - _ => "_UNKNOWN" + _ => "_OTHER" }; } diff --git a/src/Identity/Extensions.Core/src/UserManagerMetrics.cs b/src/Identity/Extensions.Core/src/UserManagerMetrics.cs index b534a0d38ce6..e0f6794b8fc3 100644 --- a/src/Identity/Extensions.Core/src/UserManagerMetrics.cs +++ b/src/Identity/Extensions.Core/src/UserManagerMetrics.cs @@ -32,12 +32,12 @@ internal sealed class UserManagerMetrics : IDisposable public UserManagerMetrics(IMeterFactory meterFactory) { _meter = meterFactory.Create(MeterName); - _createCounter = _meter.CreateCounter(CreateCounterName, "count", "The number of users created."); - _updateCounter = _meter.CreateCounter(UpdateCounterName, "count", "The number of user updates."); - _deleteCounter = _meter.CreateCounter(DeleteCounterName, "count", "The number of users deleted."); - _checkPasswordCounter = _meter.CreateCounter(CheckPasswordCounterName, "count", "The number of check password attempts. Only checks whether the password is valid and not whether the user account is in a state that can log in."); - _verifyTokenCounter = _meter.CreateCounter(VerifyTokenCounterName, "count", "The number of token verification attempts."); - _generateTokenCounter = _meter.CreateCounter(GenerateTokenCounterName, "count", "The number of token generation attempts."); + _createCounter = _meter.CreateCounter(CreateCounterName, "{user}", "The number of users created."); + _updateCounter = _meter.CreateCounter(UpdateCounterName, "{user}", "The number of users updated."); + _deleteCounter = _meter.CreateCounter(DeleteCounterName, "{user}", "The number of users deleted."); + _checkPasswordCounter = _meter.CreateCounter(CheckPasswordCounterName, "{check}", "The number of check password attempts. Only checks whether the password is valid and not whether the user account is in a state that can log in."); + _verifyTokenCounter = _meter.CreateCounter(VerifyTokenCounterName, "{count}", "The number of token verification attempts."); + _generateTokenCounter = _meter.CreateCounter(GenerateTokenCounterName, "{count}", "The number of token generation attempts."); } internal void CreateUser(string userType, IdentityResult? result, Exception? exception = null) @@ -52,7 +52,7 @@ internal void CreateUser(string userType, IdentityResult? result, Exception? exc { "aspnetcore.identity.user_type", userType } }; AddIdentityResultTags(ref tags, result); - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception, result: result); _createCounter.Add(1, tags); } @@ -70,7 +70,7 @@ internal void UpdateUser(string userType, IdentityResult? result, UserUpdateType { "aspnetcore.identity.user.update_type", GetUpdateType(updateType) }, }; AddIdentityResultTags(ref tags, result); - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception, result: result); _updateCounter.Add(1, tags); } @@ -87,7 +87,7 @@ internal void DeleteUser(string userType, IdentityResult? result, Exception? exc { "aspnetcore.identity.user_type", userType } }; AddIdentityResultTags(ref tags, result); - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception, result: result); _deleteCounter.Add(1, tags); } @@ -105,9 +105,9 @@ internal void CheckPassword(string userType, bool? userMissing, PasswordVerifica }; if (userMissing != null || result != null) { - tags.Add("aspnetcore.identity.user.password_result", GetPasswordResult(result, passwordMissing: null, userMissing)); + tags.Add("aspnetcore.identity.password_check_result", GetPasswordResult(result, passwordMissing: null, userMissing)); } - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception); _checkPasswordCounter.Add(1, tags); } @@ -128,7 +128,7 @@ internal void VerifyToken(string userType, bool? result, string purpose, Excepti { tags.Add("aspnetcore.identity.token_verified", result == true ? "success" : "failure"); } - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception); _verifyTokenCounter.Add(1, tags); } @@ -145,14 +145,14 @@ internal void GenerateToken(string userType, string purpose, Exception? exceptio { "aspnetcore.identity.user_type", userType }, { "aspnetcore.identity.token_purpose", GetTokenPurpose(purpose) }, }; - AddExceptionTags(ref tags, exception); + AddErrorTag(ref tags, exception); _generateTokenCounter.Add(1, tags); } private static string GetTokenPurpose(string purpose) { - // Purpose could be any value and can't be used as a tag value. However, there are known purposes + // Purpose could be any value and can't be used directly as a tag value. However, there are known purposes // on UserManager that we can detect and use as a tag value. Some could have a ':' in them followed by user data. // We need to trim them to content before ':' and then match to known values. ReadOnlySpan trimmedPurpose = purpose; @@ -161,7 +161,8 @@ private static string GetTokenPurpose(string purpose) { trimmedPurpose = purpose.AsSpan(0, colonIndex); } - + + // These are known purposes that are specified in ASP.NET Core Identity. return trimmedPurpose switch { "ResetPassword" => "reset_password", @@ -169,7 +170,7 @@ private static string GetTokenPurpose(string purpose) "EmailConfirmation" => "email_confirmation", "ChangeEmail" => "change_email", "TwoFactor" => "two_factor", - _ => "_UNKNOWN" + _ => "_OTHER" }; } @@ -183,15 +184,16 @@ private static void AddIdentityResultTags(ref TagList tags, IdentityResult? resu tags.Add("aspnetcore.identity.result", result.Succeeded ? "success" : "failure"); if (!result.Succeeded && result.Errors.FirstOrDefault()?.Code is { Length: > 0 } code) { - tags.Add("aspnetcore.identity.result_error_code", code); + tags.Add("aspnetcore.identity.error_code", code); } } - private static void AddExceptionTags(ref TagList tags, Exception? exception) + private static void AddErrorTag(ref TagList tags, Exception? exception, IdentityResult? result = null) { - if (exception != null) + var value = exception?.GetType().FullName ?? result?.Errors.FirstOrDefault()?.Code; + if (value != null) { - tags.Add("error.type", exception.GetType().FullName!); + tags.Add("error.type", value); } } @@ -204,7 +206,7 @@ private static string GetPasswordResult(PasswordVerificationResult? result, bool (PasswordVerificationResult.Failed, false, false) => "failure", (null, true, false) => "password_missing", (null, false, true) => "user_missing", - _ => "_UNKNOWN" + _ => "_OTHER" }; } @@ -244,7 +246,7 @@ private static string GetUpdateType(UserUpdateType updateType) UserUpdateType.RedeemTwoFactorRecoveryCode => "redeem_two_factor_recovery_code", UserUpdateType.SetPasskey => "set_passkey", UserUpdateType.RemovePasskey => "remove_passkey", - _ => "_UNKNOWN" + _ => "_OTHER" }; } diff --git a/src/Identity/test/Identity.Test/UserManagerTest.cs b/src/Identity/test/Identity.Test/UserManagerTest.cs index e82932e5e90a..69eac50cdb83 100644 --- a/src/Identity/test/Identity.Test/UserManagerTest.cs +++ b/src/Identity/test/Identity.Test/UserManagerTest.cs @@ -174,7 +174,7 @@ public async Task DeleteCallsStore_Failure() [ KeyValuePair.Create("aspnetcore.identity.user_type", "Microsoft.AspNetCore.Identity.Test.PocoUser"), KeyValuePair.Create("aspnetcore.identity.result", "failure"), - KeyValuePair.Create("aspnetcore.identity.result_error_code", "ConcurrencyFailure") + KeyValuePair.Create("aspnetcore.identity.error_code", "ConcurrencyFailure") ])); } @@ -664,7 +664,7 @@ public async Task CheckPasswordWillRehashPasswordWhenNeeded() Assert.Collection(checkPassword.GetMeasurementSnapshot(), m => MetricsHelpers.AssertContainsTags(m.Tags, [ - KeyValuePair.Create("aspnetcore.identity.user.password_result", "success_rehash_needed") + KeyValuePair.Create("aspnetcore.identity.password_check_result", "success_rehash_needed") ])); } @@ -871,7 +871,7 @@ public async Task CheckPasswordWithNullUserReturnsFalse() Assert.Collection(checkPassword.GetMeasurementSnapshot(), m => MetricsHelpers.AssertContainsTags(m.Tags, [ - KeyValuePair.Create("aspnetcore.identity.user.password_result", "user_missing") + KeyValuePair.Create("aspnetcore.identity.password_check_result", "user_missing") ])); } @@ -952,13 +952,13 @@ await Assert.ThrowsAsync( Assert.Collection(generateToken.GetMeasurementSnapshot(), m => MetricsHelpers.AssertContainsTags(m.Tags, [ - KeyValuePair.Create("aspnetcore.identity.token_purpose", "_UNKNOWN"), + KeyValuePair.Create("aspnetcore.identity.token_purpose", "_OTHER"), KeyValuePair.Create("error.type", "System.NotSupportedException"), ])); Assert.Collection(verifyToken.GetMeasurementSnapshot(), m => MetricsHelpers.AssertContainsTags(m.Tags, [ - KeyValuePair.Create("aspnetcore.identity.token_purpose", "_UNKNOWN"), + KeyValuePair.Create("aspnetcore.identity.token_purpose", "_OTHER"), KeyValuePair.Create("error.type", "System.NotSupportedException"), ])); } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy