Skip to content

Commit 79f8071

Browse files
authored
Merge pull request #48415 from holly-cummins/allow-lazy-container-info-in-log-forwarding
Allow lazy container info in log forwarding
2 parents aced827 + e8fa94c commit 79f8071

File tree

2 files changed

+49
-40
lines changed

2 files changed

+49
-40
lines changed

extensions/devservices/deployment/src/main/java/io/quarkus/devservices/deployment/ContainerLogForwarder.java

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,20 @@
1313
import org.testcontainers.containers.output.FrameConsumerResultCallback;
1414
import org.testcontainers.containers.output.OutputFrame;
1515

16+
import io.quarkus.deployment.dev.devservices.ContainerInfo;
1617
import io.quarkus.deployment.dev.devservices.DevServiceDescriptionBuildItem;
1718

1819
public class ContainerLogForwarder implements Closeable {
1920

2021
private final DevServiceDescriptionBuildItem devService;
2122
private final AtomicLong timestamp = new AtomicLong(0L);
2223
private final Logger logger;
23-
private final String shortId;
2424
private FrameConsumerResultCallback resultCallback;
2525
private final AtomicBoolean running = new AtomicBoolean(false);
2626

2727
public ContainerLogForwarder(DevServiceDescriptionBuildItem devService) {
2828
this.devService = devService;
2929
this.logger = Logger.getLogger(devService.getName());
30-
this.shortId = devService.getContainerInfo().getShortId();
3130
}
3231

3332
public DevServiceDescriptionBuildItem getDevService() {
@@ -39,22 +38,28 @@ public boolean isRunning() {
3938
}
4039

4140
public void start() {
42-
if (running.compareAndSet(false, true)) {
43-
this.resultCallback = new FrameConsumerResultCallback();
44-
this.resultCallback.addConsumer(STDOUT, frame -> {
45-
if (running.get())
46-
logger.infof("[%s] %s", shortId, updateTimestamp(frame));
47-
});
48-
this.resultCallback.addConsumer(STDERR, frame -> {
49-
if (running.get())
50-
logger.errorf("[%s] %s", shortId, updateTimestamp(frame));
51-
});
52-
DockerClientFactory.lazyClient().logContainerCmd(devService.getContainerInfo().id())
53-
.withFollowStream(true)
54-
.withStdErr(true)
55-
.withStdOut(true)
56-
.withSince(timestamp.intValue())
57-
.exec(resultCallback);
41+
ContainerInfo containerInfo = devService.getContainerInfo();
42+
43+
if (containerInfo != null) {
44+
String shortId = containerInfo.getShortId();
45+
46+
if (running.compareAndSet(false, true)) {
47+
this.resultCallback = new FrameConsumerResultCallback();
48+
this.resultCallback.addConsumer(STDOUT, frame -> {
49+
if (running.get())
50+
logger.infof("[%s] %s", shortId, updateTimestamp(frame));
51+
});
52+
this.resultCallback.addConsumer(STDERR, frame -> {
53+
if (running.get())
54+
logger.errorf("[%s] %s", shortId, updateTimestamp(frame));
55+
});
56+
DockerClientFactory.lazyClient().logContainerCmd(containerInfo.id())
57+
.withFollowStream(true)
58+
.withStdErr(true)
59+
.withStdOut(true)
60+
.withSince(timestamp.intValue())
61+
.exec(resultCallback);
62+
}
5863
}
5964
}
6065

extensions/devservices/deployment/src/main/java/io/quarkus/devservices/deployment/DevServicesProcessor.java

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import java.util.Arrays;
1414
import java.util.Collections;
1515
import java.util.Comparator;
16-
import java.util.HashMap;
1716
import java.util.HashSet;
1817
import java.util.List;
1918
import java.util.Map;
@@ -62,7 +61,7 @@ public class DevServicesProcessor {
6261

6362
static volatile ConsoleStateManager.ConsoleContext context;
6463
static volatile boolean logForwardEnabled = false;
65-
static Map<String, ContainerLogForwarder> containerLogForwarders = new HashMap<>();
64+
static Set<ContainerLogForwarder> containerLogForwarders = new HashSet<>();
6665

6766
@BuildStep
6867
public DevServicesNetworkIdBuildItem networkId(
@@ -110,15 +109,14 @@ public List<DevServiceDescriptionBuildItem> config(
110109
LaunchModeBuildItem launchModeBuildItem,
111110
Optional<DevServicesLauncherConfigResultBuildItem> devServicesLauncherConfig,
112111
List<DevServicesResultBuildItem> devServicesResults) {
112+
containerLogForwarders.clear();
113113
List<DevServiceDescriptionBuildItem> serviceDescriptions = buildServiceDescriptions(
114114
dockerStatusBuildItem, devServicesResults, devServicesLauncherConfig);
115115

116116
for (DevServiceDescriptionBuildItem devService : serviceDescriptions) {
117-
if (devService.hasContainerInfo()) {
118-
containerLogForwarders.compute(devService.getContainerInfo().id(),
119-
(id, forwarder) -> Objects.requireNonNullElseGet(forwarder,
120-
() -> new ContainerLogForwarder(devService)));
121-
}
117+
118+
containerLogForwarders.add(new ContainerLogForwarder(devService));
119+
122120
}
123121

124122
// Build commands if we are in local dev mode
@@ -131,11 +129,11 @@ public List<DevServiceDescriptionBuildItem> config(
131129

132130
// Dev UI Log stream
133131
for (DevServiceDescriptionBuildItem service : serviceDescriptions) {
134-
if (service.getContainerInfo() != null) {
135-
footerLogProducer.produce(new FooterLogBuildItem(service.getName(), () -> {
136-
return createLogPublisher(service.getContainerInfo().id());
137-
}));
138-
}
132+
133+
footerLogProducer.produce(new FooterLogBuildItem(service.getName(), () -> {
134+
ContainerInfo containerInfo = service.getContainerInfo();
135+
return createLogPublisher(containerInfo);
136+
}));
139137
}
140138

141139
if (context == null) {
@@ -162,22 +160,28 @@ public List<DevServiceDescriptionBuildItem> config(
162160
return serviceDescriptions;
163161
}
164162

165-
private Flow.Publisher<String> createLogPublisher(String containerId) {
163+
private Flow.Publisher<String> createLogPublisher(ContainerInfo containerInfo) {
164+
166165
try (FrameConsumerResultCallback resultCallback = new FrameConsumerResultCallback()) {
167166
SubmissionPublisher<String> publisher = new SubmissionPublisher<>();
168167
resultCallback.addConsumer(OutputFrame.OutputType.STDERR,
169168
frame -> publisher.submit(frame.getUtf8String()));
170169
resultCallback.addConsumer(OutputFrame.OutputType.STDOUT,
171170
frame -> publisher.submit(frame.getUtf8String()));
172-
LogContainerCmd logCmd = DockerClientFactory.lazyClient()
173-
.logContainerCmd(containerId)
174-
.withFollowStream(true)
175-
.withTailAll()
176-
.withStdErr(true)
177-
.withStdOut(true);
178-
logCmd.exec(resultCallback);
171+
if (containerInfo != null) {
172+
String containerId = containerInfo.id();
173+
LogContainerCmd logCmd = DockerClientFactory.lazyClient()
174+
.logContainerCmd(containerId)
175+
.withFollowStream(true)
176+
.withTailAll()
177+
.withStdErr(true)
178+
.withStdOut(true);
179+
logCmd.exec(resultCallback);
180+
}
179181

180182
return publisher;
183+
} catch (RuntimeException re) {
184+
throw re;
181185
} catch (Exception e) {
182186
throw new RuntimeException(e);
183187
}
@@ -259,14 +263,14 @@ private ContainerInfo.ContainerPort[] getExposedPorts(Container container) {
259263

260264
private synchronized void toggleLogForwarders() {
261265
if (logForwardEnabled) {
262-
for (ContainerLogForwarder logForwarder : containerLogForwarders.values()) {
266+
for (ContainerLogForwarder logForwarder : containerLogForwarders) {
263267
if (logForwarder.isRunning()) {
264268
logForwarder.close();
265269
}
266270
}
267271
logForwardEnabled = false;
268272
} else {
269-
for (ContainerLogForwarder logForwarder : containerLogForwarders.values()) {
273+
for (ContainerLogForwarder logForwarder : containerLogForwarders) {
270274
logForwarder.start();
271275
}
272276
logForwardEnabled = true;

0 commit comments

Comments
 (0)