Skip to content

Commit 4cdf8a1

Browse files
authored
Identity v2 logging impovements (#45296)
1 parent a687209 commit 4cdf8a1

38 files changed

+454
-443
lines changed

sdk/identity-v2/azure-identity/checkstyle-suppressions.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
<suppress files="com.azure.v2.identity.implementation.client.DevToolsClient.java" checks="JavadocMethodCheck" />
1616
<suppress files="com.azure.v2.identity.implementation.client.DevToolsClient.java" checks="MissingJavadocTypeCheck" />
1717
<suppress files="com.azure.v2.identity.implementation.client.DevToolsClient.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
18+
<suppress files="com.azure.v2.identity.implementation.client.PersistentTokenCacheImpl.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
1819
<suppress files="com.azure.v2.identity.implementation.client.AzureToolkitCacheAccessor.java" checks="MissingJavadocMethodCheck" />
1920
<suppress files="com.azure.v2.identity.implementation.client.AzureToolkitCacheAccessor.java" checks="com.azure.tools.checkstyle.checks.JavadocThrowsChecks" />
2021
<suppress files="com.azure.v2.identity.implementation.client.AzureToolkitCacheAccessor.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
2122
<suppress files="com.azure.v2.identity.implementation.client.PersistentTokenCacheImpl.java" checks="MissingJavadocMethodCheck" />
2223
<suppress files="com.azure.v2.identity.implementation.client.PersistentTokenCacheImpl.java" checks="MissingJavadocTypeCheck" />
2324
<suppress files="com.azure.v2.identity.implementation.models.PublicClientOptions.java" checks="GoodLoggingCheck" />
25+
<suppress files="com.azure.v2.identity.[\w]+Credential.java" checks="com.azure.tools.checkstyle.checks.ThrowFromClientLoggerCheck" />
2426

2527
</suppressions>

sdk/identity-v2/azure-identity/pom.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@
5959
<dependency>
6060
<groupId>io.clientcore</groupId>
6161
<artifactId>core</artifactId>
62-
<version>1.0.0-beta.9</version> <!-- {x-version-update;io.clientcore:core;dependency} -->
62+
<version>1.0.0-beta.10</version> <!-- {x-version-update;unreleased_io.clientcore:core;dependency} -->
6363
</dependency>
64+
6465
<dependency>
6566
<groupId>com.azure.v2</groupId>
6667
<artifactId>azure-core</artifactId>

sdk/identity-v2/azure-identity/src/main/java/com/azure/v2/identity/AuthorizationCodeCredential.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import io.clientcore.core.instrumentation.logging.ClientLogger;
1818
import io.clientcore.core.utils.CoreUtils;
1919

20+
import static com.azure.v2.identity.implementation.util.LoggingUtil.logAndThrowTokenError;
21+
2022
/**
2123
* <p>Authorization Code authentication in Azure is a type of authentication mechanism that allows users to
2224
* authenticate with <a href="https://learn.microsoft.com/entra/fundamentals/">Microsoft Entra ID</a>
@@ -96,9 +98,8 @@ public AccessToken getToken(TokenRequestContext request) {
9698
cache.updateCache(accessToken, publicClientOptions, request);
9799
LoggingUtil.logTokenSuccess(LOGGER, request);
98100
return accessToken;
99-
} catch (Exception e) {
100-
LoggingUtil.logTokenError(LOGGER, request, e);
101-
throw LOGGER.logThrowableAsError(new CredentialAuthenticationException(e.getMessage(), e));
101+
} catch (RuntimeException e) {
102+
throw logAndThrowTokenError(LOGGER, request, e, CredentialAuthenticationException::new);
102103
}
103104
}
104105
}

sdk/identity-v2/azure-identity/src/main/java/com/azure/v2/identity/AuthorizationCodeCredentialBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public AuthorizationCodeCredentialBuilder redirectUrl(String redirectUrl) {
8181
try {
8282
this.publicClientOptions.setRedirectUri(new URI(redirectUrl));
8383
} catch (URISyntaxException e) {
84-
throw LOGGER.logThrowableAsError(new IllegalArgumentException(e));
84+
throw LOGGER.throwableAtError().log(e, IllegalArgumentException::new);
8585
}
8686
return this;
8787
}

sdk/identity-v2/azure-identity/src/main/java/com/azure/v2/identity/AzureCliCredential.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import io.clientcore.core.credentials.oauth.AccessToken;
1414
import io.clientcore.core.instrumentation.logging.ClientLogger;
1515

16+
import static com.azure.v2.identity.implementation.util.LoggingUtil.logAndThrowTokenError;
17+
1618
/**
1719
* <p>The Azure CLI is a command-line tool that allows users to manage Azure resources from their local machine or
1820
* terminal. It allows users to
@@ -69,12 +71,11 @@ public AccessToken getToken(TokenRequestContext request) {
6971
AccessToken accessToken = devToolslClient.authenticateWithAzureCli(request);
7072
LoggingUtil.logTokenSuccess(LOGGER, request);
7173
return accessToken;
72-
} catch (Exception ex) {
73-
LoggingUtil.logTokenError(LOGGER, request, ex);
74-
if (devToolslClient.getClientOptions().isChained()) {
75-
throw LOGGER.logThrowableAsError(new CredentialUnavailableException(ex.getMessage(), ex));
76-
}
77-
throw LOGGER.logThrowableAsError(new CredentialAuthenticationException(ex.getMessage(), ex));
74+
} catch (RuntimeException ex) {
75+
throw logAndThrowTokenError(LOGGER, request, ex,
76+
devToolslClient.getClientOptions().isChained()
77+
? CredentialUnavailableException::new
78+
: CredentialAuthenticationException::new);
7879
}
7980
}
8081
}

sdk/identity-v2/azure-identity/src/main/java/com/azure/v2/identity/AzureDeveloperCliCredential.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import io.clientcore.core.credentials.oauth.AccessToken;
1414
import io.clientcore.core.instrumentation.logging.ClientLogger;
1515

16+
import static com.azure.v2.identity.implementation.util.LoggingUtil.logAndThrowTokenError;
17+
1618
/**
1719
* <p>Azure Developer CLI is a command-line interface tool that allows developers to create, manage, and deploy
1820
* resources in Azure. It's built on top of the Azure CLI and provides additional functionality specific
@@ -72,12 +74,11 @@ public AccessToken getToken(TokenRequestContext request) {
7274
AccessToken accessToken = devToolslClient.authenticateWithAzureDeveloperCli(request);
7375
LoggingUtil.logTokenSuccess(LOGGER, request);
7476
return accessToken;
75-
} catch (Exception ex) {
76-
LoggingUtil.logTokenError(LOGGER, request, ex);
77-
if (devToolslClient.getClientOptions().isChained()) {
78-
throw LOGGER.logThrowableAsError(new CredentialUnavailableException(ex.getMessage(), ex));
79-
}
80-
throw LOGGER.logThrowableAsError(new CredentialAuthenticationException(ex.getMessage(), ex));
77+
} catch (RuntimeException ex) {
78+
throw logAndThrowTokenError(LOGGER, request, ex,
79+
devToolslClient.getClientOptions().isChained()
80+
? CredentialUnavailableException::new
81+
: CredentialAuthenticationException::new);
8182
}
8283
}
8384
}

sdk/identity-v2/azure-identity/src/main/java/com/azure/v2/identity/AzurePipelinesCredential.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
import io.clientcore.core.http.models.HttpRequest;
1919
import io.clientcore.core.http.models.Response;
2020
import io.clientcore.core.instrumentation.logging.ClientLogger;
21+
import io.clientcore.core.models.CoreException;
2122
import io.clientcore.core.models.binarydata.BinaryData;
2223
import io.clientcore.core.serialization.json.JsonReader;
2324

2425
import java.io.IOException;
2526

27+
import static com.azure.v2.identity.implementation.util.LoggingUtil.logAndThrowTokenError;
28+
2629
/**
2730
* The {@link AzurePipelinesCredential} acquires a token using the Azure Pipelines service connection.
2831
* <p>
@@ -76,15 +79,15 @@ public class AzurePipelinesCredential implements TokenCredential {
7679
}
7780
message
7881
+= "For troubleshooting information see https://aka.ms/azsdk/java/identity/azurepipelinescredential/troubleshoot.";
79-
throw LOGGER.logThrowableAsError(new CredentialAuthenticationException(message));
82+
throw LOGGER.throwableAtError().log(message, CredentialAuthenticationException::new);
8083
}
8184
try (JsonReader reader = JsonReader.fromString(responseBody)) {
8285
return OidcTokenResponse.fromJson(reader).getOidcToken();
8386
}
8487
}
8588
} catch (IOException e) {
86-
throw LOGGER.logThrowableAsError(
87-
new CredentialAuthenticationException("Failed to get the client assertion token", e));
89+
throw LOGGER.throwableAtError()
90+
.log("Failed to get the client assertion token", e, CredentialAuthenticationException::new);
8891
}
8992
});
9093
this.confidentialClient = new ConfidentialClient(confidentialClientOptions);
@@ -98,16 +101,15 @@ public AccessToken getToken(TokenRequestContext request) {
98101
LoggingUtil.logTokenSuccess(LOGGER, request);
99102
return token;
100103
}
101-
} catch (Exception ignored) {
104+
} catch (RuntimeException ignored) {
102105
}
103106

104107
try {
105108
AccessToken token = confidentialClient.authenticate(request);
106109
LoggingUtil.logTokenSuccess(LOGGER, request);
107110
return token;
108-
} catch (Exception e) {
109-
LoggingUtil.logTokenError(LOGGER, request, e);
110-
throw LOGGER.logThrowableAsError(new RuntimeException(e));
111+
} catch (RuntimeException e) {
112+
throw logAndThrowTokenError(LOGGER, request, e, CoreException::from);
111113
}
112114
}
113115
}

sdk/identity-v2/azure-identity/src/main/java/com/azure/v2/identity/AzurePowerShellCredential.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import io.clientcore.core.credentials.oauth.AccessToken;
1414
import io.clientcore.core.instrumentation.logging.ClientLogger;
1515

16+
import static com.azure.v2.identity.implementation.util.LoggingUtil.logAndThrowTokenError;
17+
1618
/**
1719
* <p>The Azure Powershell is a command-line tool that allows users to manage Azure resources from their local machine
1820
* or terminal. It allows users to
@@ -68,12 +70,11 @@ public AccessToken getToken(TokenRequestContext request) {
6870
AccessToken accessToken = devToolslClient.authenticateWithAzurePowerShell(request);
6971
LoggingUtil.logTokenSuccess(LOGGER, request);
7072
return accessToken;
71-
} catch (Exception ex) {
72-
LoggingUtil.logTokenError(LOGGER, request, ex);
73-
if (devToolslClient.getClientOptions().isChained()) {
74-
throw LOGGER.logThrowableAsError(new CredentialUnavailableException(ex.getMessage(), ex));
75-
}
76-
throw LOGGER.logThrowableAsError(new CredentialAuthenticationException(ex.getMessage(), ex));
73+
} catch (RuntimeException ex) {
74+
throw logAndThrowTokenError(LOGGER, request, ex,
75+
devToolslClient.getClientOptions().isChained()
76+
? CredentialUnavailableException::new
77+
: CredentialAuthenticationException::new);
7778
}
7879
}
7980
}

sdk/identity-v2/azure-identity/src/main/java/com/azure/v2/identity/AzureToolkitCredential.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
import java.util.concurrent.atomic.AtomicReference;
1919

20+
import static com.azure.v2.identity.implementation.util.LoggingUtil.logAndThrowTokenError;
21+
2022
/**
2123
* <p>
2224
* The AzureToolkitCredential authenticates in a development environment and acquires a token on behalf of the
@@ -87,20 +89,19 @@ public AccessToken getToken(TokenRequestContext request) {
8789
if (cachedToken.get() != null) {
8890
return publicClient.authenticateWithPublicClientCache(request, cachedToken.get().getAccount());
8991
}
90-
} catch (Exception ex) {
92+
} catch (RuntimeException ex) {
9193
}
9294

9395
try {
9496
MsalToken msalToken = publicClient.authenticateWithAzureToolkit(request);
9597
cachedToken.set(msalToken);
9698
LoggingUtil.logTokenSuccess(LOGGER, request);
9799
return msalToken;
98-
} catch (Exception ex) {
99-
LoggingUtil.logTokenError(LOGGER, request, ex);
100-
if (publicClient.getClientOptions().isChained()) {
101-
throw LOGGER.logThrowableAsError(new CredentialUnavailableException(ex.getMessage(), ex));
102-
}
103-
throw LOGGER.logThrowableAsError(new CredentialAuthenticationException(ex.getMessage(), ex));
100+
} catch (RuntimeException ex) {
101+
throw logAndThrowTokenError(LOGGER, request, ex,
102+
publicClient.getClientOptions().isChained()
103+
? CredentialUnavailableException::new
104+
: CredentialAuthenticationException::new);
104105
}
105106
}
106107
}

sdk/identity-v2/azure-identity/src/main/java/com/azure/v2/identity/ChainedTokenCredential.java

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.azure.v2.identity.exceptions.CredentialUnavailableException;
1010
import io.clientcore.core.credentials.oauth.AccessToken;
1111
import io.clientcore.core.instrumentation.logging.ClientLogger;
12-
import io.clientcore.core.instrumentation.logging.LogLevel;
1312

1413
import java.util.ArrayList;
1514
import java.util.Collections;
@@ -69,61 +68,54 @@ public AccessToken getToken(TokenRequestContext request) {
6968
if (selectedCredential.get() != null && useCachedWorkingCredential) {
7069
try {
7170
AccessToken accessToken = selectedCredential.get().getToken(request);
72-
logTokenMessage("Azure Identity => Returning token from cached credential {}",
73-
selectedCredential.get());
71+
LOGGER.atInfo()
72+
.addKeyValue("credentialType", selectedCredential.get().getClass().getCanonicalName())
73+
.log("Azure Identity => Returning token from cached credential.");
7474
return accessToken;
75-
} catch (Exception e) {
75+
} catch (RuntimeException e) {
7676
handleException(e, selectedCredential.get(), exceptions,
77-
"Azure Identity => Cached credential {} is unavailable.", selectedCredential.get());
77+
"Azure Identity => Cached credential is unavailable.");
7878
}
7979
} else {
8080
for (TokenCredential credential : credentials) {
8181
try {
8282
AccessToken accessToken = credential.getToken(request);
83-
logTokenMessage("Azure Identity => Attempted credential {} returns a token", credential);
83+
LOGGER.atInfo()
84+
.addKeyValue("credentialType", selectedCredential.get().getClass().getCanonicalName())
85+
.log("Azure Identity => Attempted credential returns a token.");
8486
selectedCredential.set(credential);
8587
return accessToken;
8688

87-
} catch (Exception e) {
89+
} catch (RuntimeException e) {
8890
handleException(e, credential, exceptions,
89-
"Azure Identity => Attempted credential {} is unavailable.", credential);
91+
"Azure Identity => Attempted credential is unavailable.");
9092
}
9193
}
9294
}
9395

94-
CredentialUnavailableException last = exceptions.get(exceptions.size() - 1);
96+
String lastMessage = exceptions.get(exceptions.size() - 1).getMessage();
9597
for (int z = exceptions.size() - 2; z >= 0; z--) {
9698
CredentialUnavailableException current = exceptions.get(z);
97-
last = new CredentialUnavailableException(current.getMessage() + "\r\n" + last.getMessage()
99+
lastMessage = current.getMessage() + "\r\n" + lastMessage
98100
+ (z == 0
99101
? "To mitigate this issue, please refer to the troubleshooting guidelines here at "
100102
+ "https://aka.ms/azure-identity-java-default-azure-credential-troubleshoot"
101-
: ""));
103+
: "");
102104
}
103-
throw LOGGER.logThrowableAsError(last);
104-
}
105-
106-
private void logTokenMessage(String format, TokenCredential selectedCredential) {
107-
LOGGER.atLevel(LogLevel.INFORMATIONAL)
108-
.log(String.format(format, selectedCredential.getClass().getSimpleName()));
109-
}
110-
111-
private String getCredUnavailableMessage(TokenCredential p, Exception t) {
112-
return unavailableError + p.getClass().getSimpleName() + " authentication failed. Error Details: "
113-
+ t.getMessage();
105+
throw LOGGER.throwableAtError().log(lastMessage, CredentialUnavailableException::new);
114106
}
115107

116108
private void handleException(Exception e, TokenCredential selectedCredential,
117-
List<CredentialUnavailableException> exceptions, String logMessage, TokenCredential selectedCredential1) {
109+
List<CredentialUnavailableException> exceptions, String logMessage) {
118110
if (e.getClass() != CredentialUnavailableException.class) {
119-
throw LOGGER.logThrowableAsError(
120-
new CredentialAuthenticationException(getCredUnavailableMessage(selectedCredential, e), e));
121-
} else {
122-
if (e instanceof CredentialUnavailableException) {
123-
exceptions.add((CredentialUnavailableException) e);
124-
}
111+
112+
throw LOGGER.throwableAtError()
113+
.addKeyValue("credentialType", selectedCredential.getClass().getCanonicalName())
114+
.log(unavailableError, e, CredentialAuthenticationException::new);
125115
}
126-
logTokenMessage(logMessage, selectedCredential1);
116+
117+
exceptions.add((CredentialUnavailableException) e);
118+
LOGGER.atInfo().addKeyValue("credentialType", selectedCredential.getClass().getCanonicalName()).log(logMessage);
127119
}
128120

129121
WorkloadIdentityCredential getWorkloadIdentityCredentialIfPresent() {

0 commit comments

Comments
 (0)