diff --git a/gradle.properties b/gradle.properties index 2ef0284..37148f6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.caching=true rbcs.version = 0.5.0 -lys.version = 2026.03.26 +lys.version = 2026.04.14 gitea.maven.url = https://gitea.woggioni.net/api/packages/woggioni/maven docker.registry.url=gitea.woggioni.net diff --git a/rbcs-server/build.gradle b/rbcs-server/build.gradle index 91e5eb9..1cedc43 100644 --- a/rbcs-server/build.gradle +++ b/rbcs-server/build.gradle @@ -13,6 +13,7 @@ dependencies { implementation catalog.netty.buffer implementation catalog.netty.transport implementation catalog.netty.codec.haproxy + compileOnly catalog.opentelemetry.netty['4']['1'] api project(':rbcs-common') api project(':rbcs-api') diff --git a/rbcs-server/src/main/java/module-info.java b/rbcs-server/src/main/java/module-info.java index 627df67..a0c38d9 100644 --- a/rbcs-server/src/main/java/module-info.java +++ b/rbcs-server/src/main/java/module-info.java @@ -17,6 +17,8 @@ module net.woggioni.rbcs.server { requires io.netty.common; requires io.netty.codec; requires io.netty.codec.haproxy; + requires static io.opentelemetry.api; + requires static io.opentelemetry.instrumentation.netty_4_1; requires org.slf4j; exports net.woggioni.rbcs.server; diff --git a/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/RemoteBuildCacheServer.kt b/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/RemoteBuildCacheServer.kt index e3d76f0..708d2ba 100644 --- a/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/RemoteBuildCacheServer.kt +++ b/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/RemoteBuildCacheServer.kt @@ -68,6 +68,7 @@ import net.woggioni.rbcs.common.Xml import net.woggioni.rbcs.common.createLogger import net.woggioni.rbcs.common.debug import net.woggioni.rbcs.common.info +import net.woggioni.rbcs.server.otel.OtelIntegration import net.woggioni.rbcs.server.auth.AbstractNettyHttpAuthenticator import net.woggioni.rbcs.server.auth.Authorizer import net.woggioni.rbcs.server.auth.RoleAuthorizer @@ -431,6 +432,7 @@ class RemoteBuildCacheServer(private val cfg: Configuration) { maxChunkSize = cfg.connection.chunkSize } pipeline.addLast(HttpServerCodec(httpDecoderConfig)) + OtelIntegration.createHandler()?.let { pipeline.addLast(it) } pipeline.addLast(ReadTriggerDuplexHandler.NAME, ReadTriggerDuplexHandler()) pipeline.addLast(MaxRequestSizeHandler.NAME, MaxRequestSizeHandler(cfg.connection.maxRequestSize)) pipeline.addLast(HttpChunkContentCompressor(1024)) diff --git a/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/otel/OtelIntegration.kt b/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/otel/OtelIntegration.kt new file mode 100644 index 0000000..fcf9144 --- /dev/null +++ b/rbcs-server/src/main/kotlin/net/woggioni/rbcs/server/otel/OtelIntegration.kt @@ -0,0 +1,32 @@ +package net.woggioni.rbcs.server.otel + +import io.netty.channel.ChannelHandler +import io.opentelemetry.api.GlobalOpenTelemetry +import io.opentelemetry.instrumentation.netty.v4_1.NettyServerTelemetry +import net.woggioni.rbcs.common.createLogger +import net.woggioni.rbcs.common.warn + +object OtelIntegration { + + private val log = createLogger() + + val isAvailable: Boolean by lazy { + runCatching { + Class.forName("io.opentelemetry.api.OpenTelemetry") + }.fold( + onSuccess = { true }, + onFailure = { + log.warn { "OpenTelemetry classes not on classpath, instrumentation disabled" } + false + }, + ) + } + + fun createHandler(): ChannelHandler? { + return if (isAvailable) createHandlerInternal() else null + } + + private fun createHandlerInternal(): ChannelHandler { + return NettyServerTelemetry.create(GlobalOpenTelemetry.get()).createCombinedHandler() + } +}