From de85a861c7f2198f9a32591d8f79e40904156722 Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Tue, 14 Apr 2026 23:17:54 +0200 Subject: [PATCH] feat: wire ContainerLogForwarder into DockerRuntimeOrchestrator Co-Authored-By: Claude Opus 4.6 (1M context) --- .../runtime/DockerRuntimeOrchestrator.java | 27 +++++++++++++++++++ .../RuntimeOrchestratorAutoConfig.java | 22 ++++++++++++--- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java index 201ffb5b..29d7034a 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/DockerRuntimeOrchestrator.java @@ -31,6 +31,12 @@ public class DockerRuntimeOrchestrator implements RuntimeOrchestrator { private static final Logger log = LoggerFactory.getLogger(DockerRuntimeOrchestrator.class); private DockerClient dockerClient; + private ContainerLogForwarder logForwarder; + + public void setLogForwarder(ContainerLogForwarder logForwarder) { + this.logForwarder = logForwarder; + } + @PostConstruct public void init() { var config = DefaultDockerClientConfig.createDefaultConfigBuilder() @@ -196,4 +202,25 @@ public class DockerRuntimeOrchestrator implements RuntimeOrchestrator { } return logLines.stream(); } + + @Override + public void startLogCapture(String containerId, String appSlug, String envSlug, String tenantId) { + if (logForwarder != null) { + logForwarder.startCapture(containerId, appSlug, envSlug, tenantId); + } + } + + @Override + public void stopLogCapture(String containerId) { + if (logForwarder != null) { + logForwarder.stopCapture(containerId); + } + } + + @Override + public void stopLogCaptureByApp(String appSlug, String envSlug) { + if (logForwarder != null) { + logForwarder.stopCaptureByApp(appSlug, envSlug); + } + } } diff --git a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java index ff3bd654..a63d425f 100644 --- a/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java +++ b/cameleer3-server-app/src/main/java/com/cameleer3/server/app/runtime/RuntimeOrchestratorAutoConfig.java @@ -1,5 +1,6 @@ package com.cameleer3.server.app.runtime; +import com.cameleer3.server.app.search.ClickHouseLogStore; import com.cameleer3.server.app.storage.PostgresDeploymentRepository; import com.cameleer3.server.core.runtime.DeploymentRepository; import com.cameleer3.server.core.runtime.RuntimeOrchestrator; @@ -17,13 +18,17 @@ public class RuntimeOrchestratorAutoConfig { private static final Logger log = LoggerFactory.getLogger(RuntimeOrchestratorAutoConfig.class); @Bean - public RuntimeOrchestrator runtimeOrchestrator() { - // Auto-detect: Docker socket available? + public RuntimeOrchestrator runtimeOrchestrator( + @org.springframework.beans.factory.annotation.Autowired(required = false) + ContainerLogForwarder logForwarder) { if (Files.exists(Path.of("/var/run/docker.sock"))) { log.info("Docker socket detected - enabling Docker runtime orchestrator"); - return new DockerRuntimeOrchestrator(); + DockerRuntimeOrchestrator orchestrator = new DockerRuntimeOrchestrator(); + if (logForwarder != null) { + orchestrator.setLogForwarder(logForwarder); + } + return orchestrator; } - // TODO: K8s detection (check for service account token) log.info("No Docker socket or K8s detected - runtime management disabled (observability-only mode)"); return new DisabledRuntimeOrchestrator(); } @@ -44,4 +49,13 @@ public class RuntimeOrchestratorAutoConfig { } return null; } + + @Bean + public ContainerLogForwarder containerLogForwarder(RuntimeOrchestrator orchestrator, + ClickHouseLogStore logStore) { + if (orchestrator instanceof DockerRuntimeOrchestrator docker) { + return new ContainerLogForwarder(docker.getDockerClient(), logStore); + } + return null; + } }