forked from woggioni/rbcs
Add optional OpenTelemetry Netty server instrumentation
- Update lys.version to 2026.04.14 - Add optional compileOnly dependency on opentelemetry-netty-4.1 in rbcs-server - Add runtime guard to only activate instrumentation when OTel classes are on classpath - Insert OTel combined handler after HttpServerCodec in the Netty pipeline - Add requires-static JPMS directives for optional module support
This commit is contained in:
@@ -4,7 +4,7 @@ org.gradle.caching=true
|
|||||||
|
|
||||||
rbcs.version = 0.5.0
|
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
|
gitea.maven.url = https://gitea.woggioni.net/api/packages/woggioni/maven
|
||||||
docker.registry.url=gitea.woggioni.net
|
docker.registry.url=gitea.woggioni.net
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ dependencies {
|
|||||||
implementation catalog.netty.buffer
|
implementation catalog.netty.buffer
|
||||||
implementation catalog.netty.transport
|
implementation catalog.netty.transport
|
||||||
implementation catalog.netty.codec.haproxy
|
implementation catalog.netty.codec.haproxy
|
||||||
|
compileOnly catalog.opentelemetry.netty['4']['1']
|
||||||
|
|
||||||
api project(':rbcs-common')
|
api project(':rbcs-common')
|
||||||
api project(':rbcs-api')
|
api project(':rbcs-api')
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ module net.woggioni.rbcs.server {
|
|||||||
requires io.netty.common;
|
requires io.netty.common;
|
||||||
requires io.netty.codec;
|
requires io.netty.codec;
|
||||||
requires io.netty.codec.haproxy;
|
requires io.netty.codec.haproxy;
|
||||||
|
requires static io.opentelemetry.api;
|
||||||
|
requires static io.opentelemetry.instrumentation.netty_4_1;
|
||||||
requires org.slf4j;
|
requires org.slf4j;
|
||||||
|
|
||||||
exports net.woggioni.rbcs.server;
|
exports net.woggioni.rbcs.server;
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ import net.woggioni.rbcs.common.Xml
|
|||||||
import net.woggioni.rbcs.common.createLogger
|
import net.woggioni.rbcs.common.createLogger
|
||||||
import net.woggioni.rbcs.common.debug
|
import net.woggioni.rbcs.common.debug
|
||||||
import net.woggioni.rbcs.common.info
|
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.AbstractNettyHttpAuthenticator
|
||||||
import net.woggioni.rbcs.server.auth.Authorizer
|
import net.woggioni.rbcs.server.auth.Authorizer
|
||||||
import net.woggioni.rbcs.server.auth.RoleAuthorizer
|
import net.woggioni.rbcs.server.auth.RoleAuthorizer
|
||||||
@@ -431,6 +432,7 @@ class RemoteBuildCacheServer(private val cfg: Configuration) {
|
|||||||
maxChunkSize = cfg.connection.chunkSize
|
maxChunkSize = cfg.connection.chunkSize
|
||||||
}
|
}
|
||||||
pipeline.addLast(HttpServerCodec(httpDecoderConfig))
|
pipeline.addLast(HttpServerCodec(httpDecoderConfig))
|
||||||
|
OtelIntegration.createHandler()?.let { pipeline.addLast(it) }
|
||||||
pipeline.addLast(ReadTriggerDuplexHandler.NAME, ReadTriggerDuplexHandler())
|
pipeline.addLast(ReadTriggerDuplexHandler.NAME, ReadTriggerDuplexHandler())
|
||||||
pipeline.addLast(MaxRequestSizeHandler.NAME, MaxRequestSizeHandler(cfg.connection.maxRequestSize))
|
pipeline.addLast(MaxRequestSizeHandler.NAME, MaxRequestSizeHandler(cfg.connection.maxRequestSize))
|
||||||
pipeline.addLast(HttpChunkContentCompressor(1024))
|
pipeline.addLast(HttpChunkContentCompressor(1024))
|
||||||
|
|||||||
@@ -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<OtelIntegration>()
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user