I am trying to integrate aspect.io
(which acts as opentelmetry collector) into our microservice written using ktor-2.0
The changes are:
buid.gradle.kts
application {
mainClass.set(appMainClass)
applicationDefaultJvmArgs = listOf(
"-javaagent:$buildDir/otel/otel-javaagent.jar",
"-Dotel.service.name=mservice",
"-Dotel.exporter.otlp.traces.endpoint=https://otelcol.aspecto.io:4317",
"-Dotel.logs.otlp.headers=Authorization=<auth-token>"
)
}
val openTelemetry: Configuration by configurations.creating
dependencies {
...
implementation(platform("io.opentelemetry:opentelemetry-bom:1.32.0"))
implementation("io.opentelemetry:opentelemetry-api")
implementation("io.opentelemetry:opentelemetry-extension-kotlin")
implementation("io.opentelemetry.instrumentation:opentelemetry-ktor-2.0:1.31.0-alpha")
implementation("io.opentelemetry.instrumentation:opentelemetry-logback-appender-1.0:1.31.0-alpha")
openTelemetry("io.opentelemetry.javaagent:opentelemetry-javaagent:1.31.0")
...
}
App.kt
fun Application.main() {
...
install(KtorServerTracing) {
setOpenTelemetry(GlobalOpenTelemetry.get())
}
...
}
The changes are inspired by the open source example available here.
With this configuration, I get the following error consistently:
Exception in thread "main" io.ktor.server.application.DuplicatePluginException: Please make sure that you use unique name for the plugin and don't install it twice. Conflicting application plugin is already installed with the same key as `OpenTelemetry`
at io.ktor.server.application.ApplicationPluginKt.install(ApplicationPlugin.kt:114)
at com.knidal.platform.luna.AppKt.main(App.kt:86)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97)
at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Static.call(CallerImpl.kt:106)
at kotlin.reflect.jvm.internal.KCallableImpl.callDefaultMethod$kotlin_reflection(KCallableImpl.kt:207)
at kotlin.reflect.jvm.internal.KCallableImpl.callBy(KCallableImpl.kt:112)
at io.ktor.server.engine.internal.CallableUtilsKt.callFunctionWithInjection(CallableUtils.kt:119)
at io.ktor.server.engine.internal.CallableUtilsKt.executeModuleFunction(CallableUtils.kt:36)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$launchModuleByName$1.invoke(ApplicationEngineEnvironmentReloading.kt:332)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$launchModuleByName$1.invoke(ApplicationEngineEnvironmentReloading.kt:331)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartupFor(ApplicationEngineEnvironmentReloading.kt:356)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.launchModuleByName(ApplicationEngineEnvironmentReloading.kt:331)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.access$launchModuleByName(ApplicationEngineEnvironmentReloading.kt:32)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:312)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading$instantiateAndConfigureApplication$1.invoke(ApplicationEngineEnvironmentReloading.kt:310)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.avoidingDoubleStartup(ApplicationEngineEnvironmentReloading.kt:338)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.instantiateAndConfigureApplication(ApplicationEngineEnvironmentReloading.kt:310)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.createApplication(ApplicationEngineEnvironmentReloading.kt:150)
at io.ktor.server.engine.ApplicationEngineEnvironmentReloading.start(ApplicationEngineEnvironmentReloading.kt:277)
at io.ktor.server.netty.NettyApplicationEngine.start(NettyApplicationEngine.kt:216)
at io.ktor.server.netty.EngineMain.main(EngineMain.kt:23)
Not sure why it throws a DuplicatePluginException
. There is no other place where the plugin is being initialized. One thing to note is we use application.conf
in our service. Not sure if it is related to that or not.
Any directional guidance is appreciated. Thanks in advance!