Skip to content
5 changes: 4 additions & 1 deletion telemetry/jetbrains/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ dependencies {

tasks {
withType<KotlinCompile> {
compilerOptions.jvmTarget = JvmTarget.JVM_17
compilerOptions {
jvmTarget = JvmTarget.JVM_17
freeCompilerArgs.add("-Xcontext-receivers")
}
}

val validatePackagedSchema by registering {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import com.squareup.kotlinpoet.DOUBLE
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.FunSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.MemberName
import com.squareup.kotlinpoet.ParameterSpec
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.STRING
import com.squareup.kotlinpoet.TypeAliasSpec
import com.squareup.kotlinpoet.TypeSpec
import com.squareup.kotlinpoet.TypeVariableName
import java.io.File
import java.time.Instant

Expand All @@ -28,6 +29,7 @@ val CONNECTION_SETTINGS = ClassName("software.aws.toolkits.core", "ConnectionSet

const val RESULT = "result"
const val SUCCESS = "success"
const val SANITIZED_RESULT_TYPE_FORMAT = "MetricResult"

fun String.filterInvalidCharacters() = this.replace(".", "")

Expand Down Expand Up @@ -118,8 +120,18 @@ private fun FileSpec.Builder.generateTelemetryEnumTypes(items: List<TelemetryMet
}

private fun FileSpec.Builder.generateTelemetryEnumType(item: TelemetryMetricType): FileSpec.Builder {
val clazz = item.name.toTypeFormat()
val existsInKotlinStdlib =
try {
Class.forName("kotlin.$clazz")
true
} catch (_: ClassNotFoundException) {
false
}

val typeName = if (existsInKotlinStdlib) "Metric$clazz" else clazz
val enum =
TypeSpec.enumBuilder(item.name.toTypeFormat())
TypeSpec.enumBuilder(typeName)
.primaryConstructor(
FunSpec.constructorBuilder()
.addParameter("value", String::class)
Expand Down Expand Up @@ -152,7 +164,7 @@ private fun FileSpec.Builder.generateTelemetryEnumType(item: TelemetryMetricType
TypeSpec.companionObjectBuilder()
.addFunction(
FunSpec.builder("from")
.returns(ClassName("", item.name.toTypeFormat()))
.returns(ClassName("", typeName))
.addParameter("type", String::class)
.addStatement("return values().firstOrNull·{·it.value·==·type·} ?:·$unknownType")
.build(),
Expand All @@ -166,6 +178,33 @@ private fun FileSpec.Builder.generateTelemetryEnumType(item: TelemetryMetricType
return this
}

private fun FileSpec.Builder.generateDeprecatedOverloads(name: String): FileSpec.Builder {
val oldName = name.toTypeFormat()
val replacementType = TypeVariableName("Metric$oldName")
val replacementFqn = TypeVariableName("$PACKAGE_NAME.$replacementType")
val alias =
TypeAliasSpec.builder(oldName, replacementType)
.addAnnotation(
AnnotationSpec.builder(Deprecated::class)
.addMember("message = %S", "Name conflicts with the Kotlin standard library")
.addMember("replaceWith = ReplaceWith(%S, %S)", replacementType, replacementFqn)
.build(),
)
.build()

addTypeAlias(alias)

return this
}

private fun FileSpec.Builder.generateTelemetryObjects(schema: List<MetricSchema>): FileSpec.Builder {
schema.groupBy { it.namespace() }
.toSortedMap()
.forEach { (namespace, metrics) -> generateNamespaces(namespace, metrics) }

return this
}

private fun FileSpec.Builder.generateNamespaces(
namespace: String,
metrics: List<MetricSchema>,
Expand All @@ -181,6 +220,7 @@ private fun FileSpec.Builder.generateNamespaces(
return this
}

context(FileSpec.Builder)
private fun TypeSpec.Builder.generateRecordFunctions(metric: MetricSchema) {
// metric.name.split("_")[1] is guaranteed to work at this point because the schema requires the metric name to have at least 1 underscore
val functionName = metric.name.split("_")[1]
Expand All @@ -193,6 +233,7 @@ private fun TypeSpec.Builder.generateRecordFunctions(metric: MetricSchema) {
if (metric.metadata.none { it.type.name == RESULT }) {
return
}
generateDeprecatedOverloads(RESULT)

addFunction(buildProjectOverloadFunction(functionName, metric))
addFunction(buildConnectionSettingsOverloadFunction(functionName, metric))
Expand Down Expand Up @@ -257,7 +298,7 @@ private fun MetadataSchema.metadataToParameter(): ParameterSpec {
// Allowed values indicates an enum
val typeName =
if (type.allowedValues != null) {
ClassName(PACKAGE_NAME, type.name.toTypeFormat())
ClassName(PACKAGE_NAME, type.name.toTypeFormat().replace("Result", SANITIZED_RESULT_TYPE_FORMAT))
} else {
type.type.kotlinType()
}.copy(nullable = required == false)
Expand All @@ -273,11 +314,11 @@ private fun FunSpec.Builder.generateFunctionBody(
metadataParameter: ParameterSpec,
metric: MetricSchema,
): FunSpec.Builder {
val metricUnit = MemberName("software.amazon.awssdk.services.toolkittelemetry.model", "Unit")
val metricUnit = ClassName("software.amazon.awssdk.services.toolkittelemetry.model", "Unit")
beginControlFlow("%T.getInstance().record(${metadataParameter.name})", TELEMETRY_SERVICE)
beginControlFlow("datum(%S)", metric.name)
addStatement("createTime(createTime)")
addStatement("unit(%M.${(metric.unit ?: MetricUnit.NONE).name})", metricUnit)
addStatement("unit(%T.${(metric.unit ?: MetricUnit.NONE).name})", metricUnit)
addStatement("value(value)")
addStatement("passive(passive)")
metric.metadata.forEach {
Expand Down Expand Up @@ -351,7 +392,7 @@ private fun FunSpec.Builder.generateResultOverloadFunctionBody(
if (it.name != SUCCESS) {
it.name
} else {
"if($SUCCESS) Result.Succeeded else Result.Failed"
"if($SUCCESS) $SANITIZED_RESULT_TYPE_FORMAT.Succeeded else $SANITIZED_RESULT_TYPE_FORMAT.Failed"
}
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,27 @@ package software.aws.toolkits.telemetry
import com.intellij.openapi.project.Project
import java.time.Instant
import kotlin.Boolean
import kotlin.Deprecated
import kotlin.Double
import kotlin.Suppress
import software.amazon.awssdk.services.toolkittelemetry.model.Unit
import software.aws.toolkits.core.ConnectionSettings
import software.aws.toolkits.jetbrains.services.telemetry.MetricEventMetadata
import software.aws.toolkits.jetbrains.services.telemetry.TelemetryService

@Deprecated(
message = "Name conflicts with the Kotlin standard library",
replaceWith = ReplaceWith("MetricResult", "software.aws.toolkits.telemetry.MetricResult"),
)
public typealias Result = MetricResult

public object MetadataTelemetry {
/**
* It does not actually have a result, yep
*/
public fun hasResult(
project: Project?,
result: Result? = null,
result: MetricResult? = null,
passive: Boolean = false,
`value`: Double = 1.0,
createTime: Instant = Instant.now(),
Expand All @@ -44,7 +51,7 @@ public object MetadataTelemetry {
*/
public fun hasResult(
connectionSettings: ConnectionSettings? = null,
result: Result? = null,
result: MetricResult? = null,
passive: Boolean = false,
`value`: Double = 1.0,
createTime: Instant = Instant.now(),
Expand All @@ -67,7 +74,7 @@ public object MetadataTelemetry {
*/
public fun hasResult(
metadata: MetricEventMetadata,
result: Result? = null,
result: MetricResult? = null,
passive: Boolean = false,
`value`: Double = 1.0,
createTime: Instant = Instant.now(),
Expand Down Expand Up @@ -95,8 +102,8 @@ public object MetadataTelemetry {
`value`: Double = 1.0,
createTime: Instant = Instant.now(),
) {
hasResult(project, if(success) Result.Succeeded else Result.Failed, passive, value,
createTime)
hasResult(project, if(success) MetricResult.Succeeded else MetricResult.Failed, passive,
value, createTime)
}

/**
Expand All @@ -109,8 +116,8 @@ public object MetadataTelemetry {
`value`: Double = 1.0,
createTime: Instant = Instant.now(),
) {
hasResult(connectionSettings, if(success) Result.Succeeded else Result.Failed, passive,
value, createTime)
hasResult(connectionSettings, if(success) MetricResult.Succeeded else MetricResult.Failed,
passive, value, createTime)
}

/**
Expand All @@ -123,7 +130,7 @@ public object MetadataTelemetry {
`value`: Double = 1.0,
createTime: Instant = Instant.now(),
) {
hasResult(metadata, if(success) Result.Succeeded else Result.Failed, passive, value,
createTime)
hasResult(metadata, if(success) MetricResult.Succeeded else MetricResult.Failed, passive,
value, createTime)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import kotlin.Suppress
/**
* The result of the operation
*/
public enum class Result(
public enum class MetricResult(
private val `value`: String,
) {
Succeeded("Succeeded"),
Expand All @@ -21,6 +21,7 @@ public enum class Result(
override fun toString(): String = value

public companion object {
public fun from(type: String): Result = values().firstOrNull { it.value == type } ?: Unknown
public fun from(type: String): MetricResult = values().firstOrNull { it.value == type }
?: Unknown
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import kotlin.Suppress
/**
* The result of the operation
*/
public enum class Result(
public enum class MetricResult(
private val `value`: String,
) {
Succeeded("Succeeded"),
Expand All @@ -23,6 +23,7 @@ public enum class Result(
override fun toString(): String = value

public companion object {
public fun from(type: String): Result = values().firstOrNull { it.value == type } ?: Unknown
public fun from(type: String): MetricResult = values().firstOrNull { it.value == type }
?: Unknown
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package software.aws.toolkits.telemetry
import com.intellij.openapi.project.Project
import java.time.Instant
import kotlin.Boolean
import kotlin.Deprecated
import kotlin.Double
import kotlin.String
import kotlin.Suppress
Expand All @@ -16,6 +17,12 @@ import software.aws.toolkits.core.ConnectionSettings
import software.aws.toolkits.jetbrains.services.telemetry.MetricEventMetadata
import software.aws.toolkits.jetbrains.services.telemetry.TelemetryService

@Deprecated(
message = "Name conflicts with the Kotlin standard library",
replaceWith = ReplaceWith("MetricResult", "software.aws.toolkits.telemetry.MetricResult"),
)
public typealias Result = MetricResult

public object TestTelemetry {
/**
* Testing metric with global metadata fields
Expand All @@ -28,7 +35,7 @@ public object TestTelemetry {
reasonDesc: String? = null,
requestId: String? = null,
requestServiceType: String? = null,
result: Result? = null,
result: MetricResult? = null,
traceId: String? = null,
metricId: String? = null,
parentId: String? = null,
Expand Down Expand Up @@ -87,7 +94,7 @@ public object TestTelemetry {
reasonDesc: String? = null,
requestId: String? = null,
requestServiceType: String? = null,
result: Result? = null,
result: MetricResult? = null,
traceId: String? = null,
metricId: String? = null,
parentId: String? = null,
Expand Down Expand Up @@ -146,7 +153,7 @@ public object TestTelemetry {
reasonDesc: String? = null,
requestId: String? = null,
requestServiceType: String? = null,
result: Result? = null,
result: MetricResult? = null,
traceId: String? = null,
metricId: String? = null,
parentId: String? = null,
Expand Down Expand Up @@ -214,8 +221,8 @@ public object TestTelemetry {
createTime: Instant = Instant.now(),
) {
metric(project, duration, httpStatusCode, reason, reasonDesc, requestId, requestServiceType,
if(success) Result.Succeeded else Result.Failed, traceId, metricId, parentId,
passive, value, createTime)
if(success) MetricResult.Succeeded else MetricResult.Failed, traceId, metricId,
parentId, passive, value, createTime)
}

/**
Expand All @@ -238,8 +245,8 @@ public object TestTelemetry {
createTime: Instant = Instant.now(),
) {
metric(connectionSettings, duration, httpStatusCode, reason, reasonDesc, requestId,
requestServiceType, if(success) Result.Succeeded else Result.Failed, traceId,
metricId, parentId, passive, value, createTime)
requestServiceType, if(success) MetricResult.Succeeded else MetricResult.Failed,
traceId, metricId, parentId, passive, value, createTime)
}

/**
Expand All @@ -262,7 +269,7 @@ public object TestTelemetry {
createTime: Instant = Instant.now(),
) {
metric(metadata, duration, httpStatusCode, reason, reasonDesc, requestId,
requestServiceType, if(success) Result.Succeeded else Result.Failed, traceId,
metricId, parentId, passive, value, createTime)
requestServiceType, if(success) MetricResult.Succeeded else MetricResult.Failed,
traceId, metricId, parentId, passive, value, createTime)
}
}
Loading