Skip to content

Commit 49e31b2

Browse files
authored
Tweak otelbase classes slightly to meet requirements from generator (#5027)
* Depends on #4982 * Depends on aws/aws-toolkit-common#899 * Rename Unit -> MetricUnit directly in SDK codegen * Use newer provider convention syntax for input/output in generator task * expose `passive`/`unit`/`value` as special fields * add smoke test for `validateRequiredAttributes`
1 parent 5f74b1e commit 49e31b2

File tree

7 files changed

+72
-13
lines changed

7 files changed

+72
-13
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ mockitoKotlin = "5.4.0"
2727
mockk = "1.13.10"
2828
nimbus-jose-jwt = "9.40"
2929
node-gradle = "7.0.2"
30-
telemetryGenerator = "1.0.272"
30+
telemetryGenerator = "1.0.278"
3131
testLogger = "4.0.0"
3232
testRetry = "1.5.10"
3333
# test-only; platform provides slf4j transitively at runtime

plugins/core/core/src/software/aws/toolkits/core/telemetry/MetricEvent.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
package software.aws.toolkits.core.telemetry
55

66
import software.amazon.awssdk.services.toolkittelemetry.model.AWSProduct
7+
import software.amazon.awssdk.services.toolkittelemetry.model.MetricUnit
78
import software.aws.toolkits.core.telemetry.MetricEvent.Companion.illegalCharsRegex
89
import software.aws.toolkits.core.utils.getLogger
910
import software.aws.toolkits.core.utils.warn
1011
import java.time.Instant
11-
import software.amazon.awssdk.services.toolkittelemetry.model.Unit as MetricUnit
1212

1313
interface MetricEvent {
1414
val createTime: Instant

plugins/core/jetbrains-community/build.gradle.kts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ idea {
3232
}
3333

3434
val generateTelemetry = tasks.register<GenerateTelemetry>("generateTelemetry") {
35-
inputFiles = listOf(file("${project.projectDir}/resources/telemetryOverride.json"))
36-
outputDirectory = generatedSrcDir.get().asFile
35+
inputFiles.setFrom(file("${project.projectDir}/resources/telemetryOverride.json"))
36+
outputDirectory.set(generatedSrcDir)
3737

3838
doFirst {
39-
outputDirectory.deleteRecursively()
39+
outputDirectory.get().asFile.deleteRecursively()
4040
}
4141
}
4242

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.intellij.openapi.progress.ProcessCanceledException
1010
import com.intellij.openapi.project.Project
1111
import migration.software.aws.toolkits.jetbrains.services.telemetry.TelemetryService
1212
import software.amazon.awssdk.services.ssooidc.model.SsoOidcException
13+
import software.amazon.awssdk.services.toolkittelemetry.model.MetricUnit
1314
import software.aws.toolkits.core.ClientConnectionSettings
1415
import software.aws.toolkits.core.ConnectionSettings
1516
import software.aws.toolkits.core.TokenConnectionSettings
@@ -374,7 +375,7 @@ private fun recordLoginWithBrowser(
374375
TelemetryService.getInstance().record(null as Project?) {
375376
datum("aws_loginWithBrowser") {
376377
createTime(Instant.now())
377-
unit(software.amazon.awssdk.services.toolkittelemetry.model.Unit.NONE)
378+
unit(MetricUnit.NONE)
378379
value(1.0)
379380
passive(false)
380381
credentialSourceId?.let { metadata("credentialSourceId", it.toString()) }
@@ -398,7 +399,7 @@ private fun recordAddConnection(
398399
TelemetryService.getInstance().record(null as Project?) {
399400
datum("auth_addConnection") {
400401
createTime(Instant.now())
401-
unit(software.amazon.awssdk.services.toolkittelemetry.model.Unit.NONE)
402+
unit(MetricUnit.NONE)
402403
value(1.0)
403404
passive(false)
404405
credentialSourceId?.let { metadata("credentialSourceId", it.toString()) }

plugins/core/jetbrains-community/src/software/aws/toolkits/jetbrains/services/telemetry/otel/OtelBase.kt

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ import io.opentelemetry.context.Scope
1818
import io.opentelemetry.sdk.trace.ReadWriteSpan
1919
import kotlinx.coroutines.CoroutineScope
2020
import software.amazon.awssdk.services.toolkittelemetry.model.AWSProduct
21+
import software.amazon.awssdk.services.toolkittelemetry.model.MetricUnit
2122
import software.aws.toolkits.core.utils.error
2223
import software.aws.toolkits.core.utils.getLogger
2324
import software.aws.toolkits.core.utils.warn
2425
import software.aws.toolkits.jetbrains.isDeveloperMode
2526
import software.aws.toolkits.jetbrains.services.telemetry.PluginResolver
27+
import software.aws.toolkits.telemetry.impl.BaseSpan
2628
import java.time.Instant
2729
import java.util.concurrent.TimeUnit
2830
import kotlin.coroutines.CoroutineContext
@@ -39,12 +41,6 @@ class DefaultSpanBuilder(delegate: SpanBuilder) : AbstractSpanBuilder<DefaultSpa
3941
override fun doStartSpan() = DefaultSpan(parent, delegate.startSpan())
4042
}
4143

42-
// temporary; will be generated
43-
abstract class BaseSpan<SpanType : AbstractBaseSpan<SpanType>>(
44-
context: Context?,
45-
delegate: Span,
46-
) : AbstractBaseSpan<SpanType>(context, delegate as ReadWriteSpan)
47-
4844
abstract class AbstractSpanBuilder<
4945
BuilderType : AbstractSpanBuilder<BuilderType, SpanType>,
5046
SpanType : AbstractBaseSpan<SpanType>,
@@ -195,6 +191,9 @@ abstract class AbstractSpanBuilder<
195191

196192
abstract class AbstractBaseSpan<SpanType : AbstractBaseSpan<SpanType>>(internal val context: Context?, private val delegate: ReadWriteSpan) : Span by delegate {
197193
protected open val requiredFields: Collection<String> = emptySet()
194+
private var passive: Boolean = false
195+
private var unit: MetricUnit = MetricUnit.NONE
196+
private var value: Double = 0.0
198197

199198
/**
200199
* Same as [com.intellij.platform.diagnostic.telemetry.helpers.use] except downcasts to specific subclass of [BaseSpan]
@@ -221,6 +220,21 @@ abstract class AbstractBaseSpan<SpanType : AbstractBaseSpan<SpanType>>(internal
221220
delegate.end()
222221
}
223222

223+
fun passive(passive: Boolean): SpanType {
224+
this.passive = passive
225+
return this as SpanType
226+
}
227+
228+
fun unit(unit: MetricUnit): SpanType {
229+
this.unit = unit
230+
return this as SpanType
231+
}
232+
233+
fun value(value: Number): SpanType {
234+
this.value = value.toDouble()
235+
return this as SpanType
236+
}
237+
224238
private fun validateRequiredAttributes() {
225239
val missingFields = requiredFields.filter { delegate.getAttribute(AttributeKey.stringKey(it)) == null }
226240
val message = { "${delegate.name} is missing required fields: ${missingFields.joinToString(", ")}" }

plugins/core/jetbrains-community/tst/software/aws/toolkits/jetbrains/services/telemetry/otel/OtelBaseTest.kt

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package software.aws.toolkits.jetbrains.services.telemetry.otel
55

66
import com.intellij.openapi.application.ApplicationManager
77
import com.intellij.testFramework.ApplicationExtension
8+
import io.opentelemetry.api.trace.Span
89
import io.opentelemetry.api.trace.TraceId
910
import io.opentelemetry.context.Context
1011
import io.opentelemetry.extension.kotlin.asContextElement
@@ -17,25 +18,46 @@ import kotlinx.coroutines.runBlocking
1718
import kotlinx.coroutines.test.runTest
1819
import org.assertj.core.api.Assertions.assertThat
1920
import org.junit.jupiter.api.Test
21+
import org.junit.jupiter.api.assertDoesNotThrow
22+
import org.junit.jupiter.api.assertThrows
2023
import org.junit.jupiter.api.extension.AfterAllCallback
2124
import org.junit.jupiter.api.extension.AfterEachCallback
2225
import org.junit.jupiter.api.extension.ExtendWith
2326
import org.junit.jupiter.api.extension.ExtensionContext
2427
import org.junit.jupiter.api.extension.RegisterExtension
28+
import org.junit.jupiter.params.ParameterizedTest
29+
import org.junit.jupiter.params.provider.Arguments
30+
import org.junit.jupiter.params.provider.MethodSource
2531
import software.amazon.awssdk.services.toolkittelemetry.model.AWSProduct
2632
import software.aws.toolkits.core.utils.getLogger
2733
import software.aws.toolkits.core.utils.warn
2834
import software.aws.toolkits.jetbrains.core.coroutines.getCoroutineBgContext
2935
import software.aws.toolkits.jetbrains.utils.pluginAwareExecuteOnPooledThread
3036
import software.aws.toolkits.jetbrains.utils.satisfiesKt
3137
import software.aws.toolkits.jetbrains.utils.spinUntil
38+
import software.aws.toolkits.telemetry.MetricResult
39+
import software.aws.toolkits.telemetry.Telemetry
40+
import java.time.Instant
3241
import java.util.concurrent.TimeUnit
42+
import java.util.stream.Stream
3343

3444
@ExtendWith(ApplicationExtension::class)
3545
class OtelBaseTest {
3646
private companion object {
3747
@RegisterExtension
3848
val otelExtension = OtelExtension()
49+
50+
private fun spanEndArgs() = Stream.of(
51+
Arguments.of("end()", { span: Span -> span.end() }),
52+
Arguments.of("end(long, TimeUnit)", { span: Span -> span.end(1, TimeUnit.SECONDS) }),
53+
Arguments.of("end(Instant)", { span: Span -> span.end(Instant.now()) }),
54+
)
55+
56+
@JvmStatic
57+
fun `AbstractBaseSpan#end() throws if attributes are missing`() = spanEndArgs()
58+
59+
@JvmStatic
60+
fun `AbstractBaseSpan#end() does not throw if all required attributes are present`() = spanEndArgs()
3961
}
4062

4163
@Test
@@ -268,6 +290,22 @@ class OtelBaseTest {
268290
}
269291
}
270292

293+
@ParameterizedTest(name = "{0}")
294+
@MethodSource
295+
fun `AbstractBaseSpan#end() throws if attributes are missing`(ignored: String, block: Span.() -> Unit) {
296+
val span = Telemetry.aws.openUrl.startSpan()
297+
val e = assertThrows<Exception> { block(span) }
298+
assertThat(e.message).contains("aws_openUrl is missing required fields: result")
299+
}
300+
301+
@ParameterizedTest(name = "{0}")
302+
@MethodSource
303+
fun `AbstractBaseSpan#end() does not throw if all required attributes are present`(ignored: String, block: Span.() -> Unit) {
304+
val span = Telemetry.aws.openUrl.startSpan()
305+
span.result(MetricResult.Succeeded)
306+
assertDoesNotThrow { block(span) }
307+
}
308+
271309
private fun spanBuilder(tracer: String, spanName: String) = DefaultSpanBuilder(otelExtension.sdk.sdk.getTracer(tracer).spanBuilder(spanName))
272310
}
273311

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"renameShapes": {
3+
// "Unit" conflicts with Kotlin stdlib [kotlin.Unit]
4+
"Unit" : "MetricUnit"
5+
}
6+
}

0 commit comments

Comments
 (0)