This commit is contained in:
@@ -4,7 +4,7 @@ org.gradle.caching=true
|
||||
|
||||
rbcs.version = 0.5.0
|
||||
|
||||
lys.version = 2026.04.28
|
||||
lys.version = 2026.04.29
|
||||
|
||||
gitea.maven.url = https://gitea.woggioni.net/api/packages/woggioni/maven
|
||||
docker.registry.url=gitea.woggioni.net
|
||||
|
||||
@@ -11,6 +11,7 @@ dependencies {
|
||||
api catalog.netty.buffer
|
||||
api catalog.netty.handler
|
||||
api catalog.netty.codec.http
|
||||
api catalog.jetbrains.annotations
|
||||
}
|
||||
|
||||
publishing {
|
||||
|
||||
@@ -8,7 +8,7 @@ module net.woggioni.rbcs.api {
|
||||
requires io.netty.buffer;
|
||||
requires org.slf4j;
|
||||
requires java.xml;
|
||||
|
||||
requires org.jetbrains.annotations;
|
||||
|
||||
exports net.woggioni.rbcs.api;
|
||||
exports net.woggioni.rbcs.api.exception;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.woggioni.rbcs.api;
|
||||
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface TelemetryController {
|
||||
void initialize();
|
||||
@NotNull ChannelHandler createHandler();
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
module net.woggioni.rbcs.cli {
|
||||
requires org.slf4j;
|
||||
requires net.woggioni.jwo;
|
||||
requires net.woggioni.rbcs.server;
|
||||
requires info.picocli;
|
||||
requires net.woggioni.rbcs.common;
|
||||
requires net.woggioni.rbcs.client;
|
||||
requires kotlin.stdlib;
|
||||
requires net.woggioni.jwo;
|
||||
requires net.woggioni.rbcs.api;
|
||||
|
||||
exports net.woggioni.rbcs.cli.impl.converters to info.picocli;
|
||||
@@ -14,4 +14,6 @@ module net.woggioni.rbcs.cli {
|
||||
opens net.woggioni.rbcs.cli to info.picocli, net.woggioni.rbcs.common;
|
||||
|
||||
exports net.woggioni.rbcs.cli;
|
||||
|
||||
uses net.woggioni.rbcs.api.TelemetryController;
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package net.woggioni.rbcs.cli
|
||||
|
||||
import net.woggioni.jwo.Application
|
||||
import net.woggioni.jwo.LoggerController
|
||||
import net.woggioni.rbcs.api.TelemetryController
|
||||
import net.woggioni.rbcs.cli.impl.AbstractVersionProvider
|
||||
import net.woggioni.rbcs.cli.impl.RbcsCommand
|
||||
import net.woggioni.rbcs.cli.impl.commands.BenchmarkCommand
|
||||
@@ -14,6 +16,8 @@ import net.woggioni.rbcs.common.RbcsUrlStreamHandlerFactory
|
||||
import net.woggioni.rbcs.common.createLogger
|
||||
import picocli.CommandLine
|
||||
import picocli.CommandLine.Model.CommandSpec
|
||||
import java.util.ServiceLoader
|
||||
import net.woggioni.rbcs.common.RBCS.loadService
|
||||
|
||||
|
||||
@CommandLine.Command(
|
||||
@@ -61,6 +65,10 @@ class RemoteBuildCacheServerCli : RbcsCommand() {
|
||||
|
||||
@JvmStatic
|
||||
fun main(vararg args: String) {
|
||||
loadService(TelemetryController::class.java)
|
||||
.firstOrNull()
|
||||
?.initialize()
|
||||
LoggerController.initializeLoggers()
|
||||
System.exit(createCommandLine().execute(*args))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.woggioni.rbcs.common
|
||||
|
||||
import io.netty.channel.Channel
|
||||
import io.netty.channel.ChannelHandlerContext
|
||||
import net.woggioni.jwo.LoggerController
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.logging.LogManager
|
||||
@@ -11,8 +12,10 @@ import org.slf4j.MDC
|
||||
import org.slf4j.event.Level
|
||||
import org.slf4j.spi.LoggingEventBuilder
|
||||
|
||||
inline fun <reified T> T.contextLogger() = LoggerFactory.getLogger(T::class.java)
|
||||
inline fun <reified T> createLogger() = LoggerFactory.getLogger(T::class.java)
|
||||
fun <T> lazyLogger(cls: Class<T>) = LoggerController.lazyLogger(cls)
|
||||
|
||||
inline fun <reified T> T.contextLogger() = lazyLogger(T::class.java)
|
||||
inline fun <reified T> createLogger() = lazyLogger(T::class.java)
|
||||
|
||||
inline fun Logger.traceParam(messageBuilder: () -> Pair<String, Array<Any>>) {
|
||||
if (isTraceEnabled) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package net.woggioni.rbcs.common
|
||||
|
||||
import net.woggioni.jwo.JWO
|
||||
import net.woggioni.jwo.Tuple2
|
||||
import java.io.IOException
|
||||
import java.net.InetAddress
|
||||
import java.net.ServerSocket
|
||||
@@ -9,18 +11,10 @@ import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.security.KeyStore
|
||||
import java.security.MessageDigest
|
||||
import java.security.cert.CertPathValidator
|
||||
import java.security.cert.CertPathValidatorException
|
||||
import java.security.cert.CertificateException
|
||||
import java.security.cert.CertificateFactory
|
||||
import java.security.cert.PKIXParameters
|
||||
import java.security.cert.PKIXRevocationChecker
|
||||
import java.security.cert.X509Certificate
|
||||
import java.util.EnumSet
|
||||
import java.security.cert.*
|
||||
import java.util.*
|
||||
import javax.net.ssl.TrustManagerFactory
|
||||
import javax.net.ssl.X509TrustManager
|
||||
import net.woggioni.jwo.JWO
|
||||
import net.woggioni.jwo.Tuple2
|
||||
|
||||
object RBCS {
|
||||
fun String.toUrl(): URL = URL.of(URI(this), null)
|
||||
@@ -164,4 +158,10 @@ object RBCS {
|
||||
.single() as X509TrustManager
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T, reified U> U.loadService(serviceClass : Class<T>): Sequence<T> {
|
||||
return (U::class.java.module.layer?.let { layer ->
|
||||
ServiceLoader.load(layer, serviceClass)
|
||||
} ?: ServiceLoader.load(serviceClass)).asSequence()
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,20 @@ plugins {
|
||||
}
|
||||
|
||||
configurations {
|
||||
|
||||
bundle {
|
||||
canBeResolved = false
|
||||
canBeConsumed = false
|
||||
transitive = true
|
||||
}
|
||||
|
||||
filteredBundle {
|
||||
canBeResolved = true
|
||||
canBeConsumed = false
|
||||
transitive = true
|
||||
|
||||
extendsFrom bundle
|
||||
|
||||
resolutionStrategy {
|
||||
dependencies {
|
||||
exclude group: 'org.slf4j', module: 'slf4j-api'
|
||||
@@ -19,27 +28,39 @@ configurations {
|
||||
}
|
||||
}
|
||||
|
||||
implementation {
|
||||
extendsFrom bundle
|
||||
}
|
||||
|
||||
release {
|
||||
transitive = false
|
||||
canBeConsumed = true
|
||||
canBeResolved = true
|
||||
}
|
||||
|
||||
compileOnly {
|
||||
extendsFrom bundle
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
bundle catalog.opentelemetry.netty['4']['1']
|
||||
compileOnly project(':rbcs-common')
|
||||
compileOnly project(':rbcs-api')
|
||||
|
||||
compileOnly catalog.netty.transport
|
||||
compileOnly catalog.slf4j.api
|
||||
compileOnly catalog.kotlin.stdlib.jdk8
|
||||
compileOnly catalog.logback.core
|
||||
compileOnly catalog.logback.classic
|
||||
|
||||
bundle catalog.opentelemetry.netty.'4'.'1'
|
||||
bundle catalog.opentelemetry.sdk.extension.autoconfigure
|
||||
bundle catalog.opentelemetry.logback.appender['1']['0']
|
||||
bundle catalog.opentelemetry.logback.appender.'1'.'0'
|
||||
bundle catalog.opentelemetry.logback.mdc.'1'.'0'
|
||||
bundle catalog.opentelemetry.extension.trace.propagators
|
||||
bundle catalog.opentelemetry.exporter.otlp
|
||||
bundle catalog.opentelemetry.runtime.telemetry
|
||||
}
|
||||
|
||||
Provider<Tar> bundleTask = tasks.register("bundle", Tar) {
|
||||
from(configurations.bundle)
|
||||
from(tasks.named(JavaPlugin.JAR_TASK_NAME))
|
||||
from(configurations.filteredBundle)
|
||||
group = BasePlugin.BUILD_GROUP
|
||||
}
|
||||
|
||||
|
||||
20
rbcs-server-otel/src/main/java/module-info.java
Normal file
20
rbcs-server-otel/src/main/java/module-info.java
Normal file
@@ -0,0 +1,20 @@
|
||||
module net.woggioni.rbcs.server.otel {
|
||||
requires net.woggioni.rbcs.common;
|
||||
requires kotlin.stdlib;
|
||||
requires io.netty.transport;
|
||||
requires io.netty.common;
|
||||
requires io.netty.buffer;
|
||||
requires org.slf4j;
|
||||
|
||||
requires ch.qos.logback.core;
|
||||
requires ch.qos.logback.classic;
|
||||
requires io.opentelemetry.api;
|
||||
requires io.opentelemetry.sdk.autoconfigure;
|
||||
requires io.opentelemetry.instrumentation.runtime_telemetry;
|
||||
requires io.opentelemetry.instrumentation.netty_4_1;
|
||||
requires io.opentelemetry.instrumentation.logback_appender_1_0;
|
||||
requires io.opentelemetry.extension.trace.propagation;
|
||||
requires net.woggioni.rbcs.api;
|
||||
|
||||
provides net.woggioni.rbcs.api.TelemetryController with net.woggioni.rbcs.server.otel.OtelController;
|
||||
}
|
||||
@@ -2,13 +2,17 @@ package net.woggioni.rbcs.server.otel
|
||||
|
||||
import io.netty.channel.ChannelHandler
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry
|
||||
import io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender
|
||||
import io.opentelemetry.instrumentation.netty.v4_1.NettyServerTelemetry
|
||||
import io.opentelemetry.instrumentation.runtimetelemetry.RuntimeTelemetry
|
||||
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk
|
||||
import net.woggioni.rbcs.api.TelemetryController
|
||||
import net.woggioni.rbcs.common.createLogger
|
||||
import net.woggioni.rbcs.common.info
|
||||
|
||||
object OtelSdkIntegration {
|
||||
class OtelController : TelemetryController {
|
||||
|
||||
private val log = createLogger<OtelSdkIntegration>()
|
||||
private val log = createLogger<OtelController>()
|
||||
|
||||
private val appenderAvailable: Boolean by lazy {
|
||||
runCatching {
|
||||
@@ -22,30 +26,28 @@ object OtelSdkIntegration {
|
||||
)
|
||||
}
|
||||
|
||||
fun initialize() {
|
||||
override fun initialize() {
|
||||
log.info { "Initializing OpenTelemetry SDK with auto-configuration" }
|
||||
|
||||
val sdk = io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk.builder()
|
||||
val sdk = AutoConfiguredOpenTelemetrySdk.builder()
|
||||
.setResultAsGlobal()
|
||||
.build()
|
||||
.openTelemetrySdk
|
||||
RuntimeTelemetry.create(sdk)
|
||||
|
||||
if (appenderAvailable) {
|
||||
runCatching {
|
||||
val clazz = Class.forName("io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender")
|
||||
clazz.getMethod("install", Class.forName("io.opentelemetry.api.OpenTelemetry"))
|
||||
.invoke(null, sdk)
|
||||
OpenTelemetryAppender.install(sdk)
|
||||
log.info { "OpenTelemetry logback appender installed" }
|
||||
}.onFailure { ex ->
|
||||
val msg = ex.localizedMessage ?: ex.javaClass.name
|
||||
log.info { "Failed to install OpenTelemetry logback appender: $msg" }
|
||||
}
|
||||
}
|
||||
|
||||
log.info { "OpenTelemetry SDK initialized successfully" }
|
||||
}
|
||||
|
||||
fun createHandler(): ChannelHandler {
|
||||
override fun createHandler(): ChannelHandler {
|
||||
return NettyServerTelemetry.create(GlobalOpenTelemetry.get()).createCombinedHandler()
|
||||
}
|
||||
}
|
||||
@@ -17,11 +17,6 @@ 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 static io.opentelemetry.sdk.autoconfigure;
|
||||
requires static io.opentelemetry.instrumentation.logback_appender_1_0;
|
||||
requires static io.opentelemetry.extension.trace.propagation;
|
||||
requires org.slf4j;
|
||||
|
||||
exports net.woggioni.rbcs.server;
|
||||
@@ -31,5 +26,6 @@ module net.woggioni.rbcs.server {
|
||||
|
||||
|
||||
uses CacheProvider;
|
||||
uses net.woggioni.rbcs.api.TelemetryController;
|
||||
provides CacheProvider with FileSystemCacheProvider, InMemoryCacheProvider;
|
||||
}
|
||||
@@ -26,12 +26,14 @@ import io.netty.util.AttributeKey
|
||||
import io.netty.util.concurrent.EventExecutorGroup
|
||||
import net.woggioni.rbcs.api.AsyncCloseable
|
||||
import net.woggioni.rbcs.api.Configuration
|
||||
import net.woggioni.rbcs.api.TelemetryController
|
||||
import net.woggioni.rbcs.api.exception.ConfigurationException
|
||||
import net.woggioni.rbcs.common.*
|
||||
import net.woggioni.rbcs.common.PasswordSecurity.decodePasswordHash
|
||||
import net.woggioni.rbcs.common.PasswordSecurity.hashPassword
|
||||
import net.woggioni.rbcs.common.RBCS.getTrustManager
|
||||
import net.woggioni.rbcs.common.RBCS.loadKeystore
|
||||
import net.woggioni.rbcs.common.RBCS.loadService
|
||||
import net.woggioni.rbcs.common.RBCS.toUrl
|
||||
import net.woggioni.rbcs.server.auth.AbstractNettyHttpAuthenticator
|
||||
import net.woggioni.rbcs.server.auth.Authorizer
|
||||
@@ -43,7 +45,6 @@ import net.woggioni.rbcs.server.handler.MaxRequestSizeHandler
|
||||
import net.woggioni.rbcs.server.handler.ProxyProtocolHandler
|
||||
import net.woggioni.rbcs.server.handler.ReadTriggerDuplexHandler
|
||||
import net.woggioni.rbcs.server.handler.ServerHandler
|
||||
import net.woggioni.rbcs.server.otel.OtelSdkIntegration
|
||||
import net.woggioni.rbcs.server.throttling.BucketManager
|
||||
import net.woggioni.rbcs.server.throttling.ThrottlingHandler
|
||||
import java.io.OutputStream
|
||||
@@ -415,7 +416,10 @@ class RemoteBuildCacheServer(private val cfg: Configuration) {
|
||||
}
|
||||
pipeline.addLast(HttpServerCodec(httpDecoderConfig))
|
||||
if(cfg.isEnableTelemetry) {
|
||||
OtelSdkIntegration.createHandler().let { pipeline.addLast(it) }
|
||||
loadService(TelemetryController::class.java)
|
||||
.firstOrNull()
|
||||
?.createHandler()
|
||||
?.let { pipeline.addLast(it) }
|
||||
}
|
||||
pipeline.addLast(ReadTriggerDuplexHandler.NAME, ReadTriggerDuplexHandler())
|
||||
pipeline.addLast(MaxRequestSizeHandler.NAME, MaxRequestSizeHandler(cfg.connection.maxRequestSize))
|
||||
@@ -511,9 +515,6 @@ class RemoteBuildCacheServer(private val cfg: Configuration) {
|
||||
}
|
||||
|
||||
fun run(): ServerHandle {
|
||||
if(cfg.isEnableTelemetry) {
|
||||
OtelSdkIntegration.initialize()
|
||||
}
|
||||
// Create the multithreaded event loops for the server
|
||||
val bossGroup = MultiThreadIoEventLoopGroup(1, NioIoHandler.newFactory())
|
||||
val channelFactory = ChannelFactory<SocketChannel> { NioSocketChannel() }
|
||||
|
||||
Reference in New Issue
Block a user