Skip to content

Commit 452e51c

Browse files
committed
telemetry(auth): emit metric for createToken
1 parent 3249e0e commit 452e51c

File tree

3 files changed

+96
-19
lines changed

3 files changed

+96
-19
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ mockitoKotlin = "5.4.1-SNAPSHOT"
2828
mockk = "1.13.17"
2929
nimbus-jose-jwt = "9.40"
3030
node-gradle = "7.0.2"
31-
telemetryGenerator = "1.0.329"
31+
telemetryGenerator = "1.0.338"
3232
testLogger = "4.0.0"
3333
testRetry = "1.5.10"
3434
# test-only; platform provides slf4j transitively at runtime

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/SsoAccessTokenProvider.kt

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,36 @@ class SsoAccessTokenProvider(
338338
throw ProcessCanceledException(IllegalStateException("Login canceled by user"))
339339
}
340340

341-
val tokenResponse = client.createToken {
342-
it.clientId(registration.clientId)
343-
it.clientSecret(registration.clientSecret)
344-
it.grantType(DEVICE_GRANT_TYPE)
345-
it.deviceCode(authorization.deviceCode)
341+
val startTime = clock.instant()
342+
val tokenResponse = try {
343+
client.createToken {
344+
it.clientId(registration.clientId)
345+
it.clientSecret(registration.clientSecret)
346+
it.grantType(DEVICE_GRANT_TYPE)
347+
it.deviceCode(authorization.deviceCode)
348+
}.also { response ->
349+
val duration = Duration.between(startTime, clock.instant()).toMillis().toDouble()
350+
AuthTelemetry.ssoTokenOperation(
351+
result = Result.Succeeded,
352+
grantType = DEVICE_GRANT_TYPE,
353+
duration = duration,
354+
requestId = response.responseMetadata()?.requestId()
355+
)
356+
LOG.info { "SSO token operation succeeded: grantType=$DEVICE_GRANT_TYPE, duration=${duration}ms" }
357+
}
358+
} catch (e: Exception) {
359+
val duration = Duration.between(startTime, clock.instant()).toMillis().toDouble()
360+
val requestId = (e as? AwsServiceException)?.requestId()
361+
AuthTelemetry.ssoTokenOperation(
362+
result = Result.Failed,
363+
grantType = DEVICE_GRANT_TYPE,
364+
duration = duration,
365+
reason = e::class.simpleName,
366+
reasonDesc = e.message?.let { scrubNames(it) },
367+
requestId = requestId
368+
)
369+
LOG.warn { "SSO token operation failed: grantType=$DEVICE_GRANT_TYPE, duration=${duration}ms, error=${e::class.simpleName}" }
370+
throw e
346371
}
347372

348373
onPendingToken.tokenRetrieved()
@@ -459,11 +484,36 @@ class SsoAccessTokenProvider(
459484

460485
stageName = RefreshCredentialStage.CREATE_TOKEN
461486
try {
462-
val newToken = client.createToken {
463-
it.clientId(registration.clientId)
464-
it.clientSecret(registration.clientSecret)
465-
it.grantType(REFRESH_GRANT_TYPE)
466-
it.refreshToken(currentToken.refreshToken)
487+
val startTime = clock.instant()
488+
val newToken = try {
489+
client.createToken {
490+
it.clientId(registration.clientId)
491+
it.clientSecret(registration.clientSecret)
492+
it.grantType(REFRESH_GRANT_TYPE)
493+
it.refreshToken(currentToken.refreshToken)
494+
}.also { response ->
495+
val duration = Duration.between(startTime, clock.instant()).toMillis().toDouble()
496+
AuthTelemetry.ssoTokenOperation(
497+
result = Result.Succeeded,
498+
grantType = REFRESH_GRANT_TYPE,
499+
duration = duration,
500+
requestId = response.responseMetadata()?.requestId()
501+
)
502+
LOG.info { "SSO token operation succeeded: grantType=$REFRESH_GRANT_TYPE, duration=${duration}ms" }
503+
}
504+
} catch (e: Exception) {
505+
val duration = Duration.between(startTime, clock.instant()).toMillis().toDouble()
506+
val requestId = (e as? AwsServiceException)?.requestId()
507+
AuthTelemetry.ssoTokenOperation(
508+
result = Result.Failed,
509+
grantType = REFRESH_GRANT_TYPE,
510+
duration = duration,
511+
reason = e::class.simpleName,
512+
reasonDesc = e.message?.let { scrubNames(it) },
513+
requestId = requestId
514+
)
515+
LOG.warn { "SSO token operation failed: grantType=$REFRESH_GRANT_TYPE, duration=${duration}ms, error=${e::class.simpleName}" }
516+
throw e
467517
}
468518

469519
stageName = RefreshCredentialStage.GET_TOKEN_DETAILS

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/core/credentials/sso/pkce/ToolkitOAuthService.kt

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ import java.math.BigInteger
4040
import java.time.Instant
4141
import java.util.Base64
4242
import java.util.concurrent.CompletableFuture
43+
import software.aws.toolkits.jetbrains.services.telemetry.scrubNames
44+
import software.aws.toolkits.telemetry.AuthTelemetry
45+
import software.aws.toolkits.telemetry.Result
4346

4447
const val PKCE_CLIENT_NAME = "AWS IDE Plugins for JetBrains"
4548

@@ -149,15 +152,39 @@ internal class ToolkitOauthCredentialsAcquirer(
149152
private val redirectUri: String,
150153
) : OAuthCredentialsAcquirer<AccessToken> {
151154
override fun acquireCredentials(code: String): OAuthCredentialsAcquirer.AcquireCredentialsResult<AccessToken> {
152-
val token = buildUnmanagedSsoOidcClient(registration.region).use { client ->
153-
client.createToken {
154-
it.clientId(registration.clientId)
155-
it.clientSecret(registration.clientSecret)
156-
it.grantType("authorization_code")
157-
it.redirectUri(redirectUri)
158-
it.codeVerifier(codeVerifier)
159-
it.code(code)
155+
val grantType = "authorization_code"
156+
val startTime = Instant.now()
157+
val token = try {
158+
buildUnmanagedSsoOidcClient(registration.region).use { client ->
159+
client.createToken {
160+
it.clientId(registration.clientId)
161+
it.clientSecret(registration.clientSecret)
162+
it.grantType(grantType)
163+
it.redirectUri(redirectUri)
164+
it.codeVerifier(codeVerifier)
165+
it.code(code)
166+
}.also { response ->
167+
val duration = java.time.Duration.between(startTime, Instant.now()).toMillis().toDouble()
168+
AuthTelemetry.ssoTokenOperation(
169+
result = Result.Succeeded,
170+
grantType = grantType,
171+
duration = duration,
172+
requestId = response.responseMetadata()?.requestId()
173+
)
174+
}
160175
}
176+
} catch (e: Exception) {
177+
val duration = java.time.Duration.between(startTime, Instant.now()).toMillis().toDouble()
178+
val requestId = (e as? software.amazon.awssdk.awscore.exception.AwsServiceException)?.requestId()
179+
AuthTelemetry.ssoTokenOperation(
180+
result = Result.Failed,
181+
grantType = grantType,
182+
duration = duration,
183+
reason = e::class.simpleName,
184+
reasonDesc = e.message?.let { scrubNames(it) },
185+
requestId = requestId
186+
)
187+
throw e
161188
}
162189

163190
return OAuthCredentialsAcquirer.AcquireCredentialsResult.Success(

0 commit comments

Comments
 (0)