Skip to content

Commit 9593f4c

Browse files
committed
ConsoleLogAppender sends log messages back to GoCD
1 parent 36cee9a commit 9593f4c

15 files changed

+189
-91
lines changed

src/main/java/cd/go/contrib/elasticagents/docker/AgentInstances.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ public interface AgentInstances<T> {
2929
* <p>
3030
* So that instances created are auto-registered with the server, the agent instance MUST have an
3131
* <code>autoregister.properties</code> file.
32-
*
3332
* @param request the request object
3433
* @param pluginRequest  the plugin request object
34+
* @param consoleLogAppender appender for console log
3535
*/
36-
T create(CreateAgentRequest request, PluginRequest pluginRequest) throws Exception;
36+
T create(CreateAgentRequest request, PluginRequest pluginRequest, ConsoleLogAppender consoleLogAppender) throws Exception;
3737

3838
/**
3939
* This message is sent when the plugin needs to terminate the agent instance.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package cd.go.contrib.elasticagents.docker;
2+
3+
import java.util.function.Consumer;
4+
5+
public interface ConsoleLogAppender extends Consumer<String> {
6+
}

src/main/java/cd/go/contrib/elasticagents/docker/Constants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public interface Constants {
3030
// The extension point API version that this plugin understands
3131
String PROCESSOR_API_VERSION = "1.0";
3232
String EXTENSION_API_VERSION = "5.0";
33+
String CONSOLE_LOG_API_VERSION = "1.0";
3334

3435
// the identifier of this plugin
3536
GoPluginIdentifier PLUGIN_IDENTIFIER = new GoPluginIdentifier(EXTENSION_TYPE, Collections.singletonList(EXTENSION_API_VERSION));
@@ -40,6 +41,7 @@ public interface Constants {
4041
String REQUEST_SERVER_DELETE_AGENT = REQUEST_SERVER_PREFIX + ".elastic-agents.delete-agents";
4142
String REQUEST_SERVER_LIST_AGENTS = REQUEST_SERVER_PREFIX + ".elastic-agents.list-agents";
4243
String REQUEST_SERVER_SERVER_HEALTH_ADD_MESSAGES = REQUEST_SERVER_PREFIX + ".server-health.add-messages";
44+
String REQUEST_SERVER_APPEND_TO_CONSOLE_LOG = REQUEST_SERVER_PREFIX + ".console-log.append";
4345

4446
// internal use only
4547
String CREATED_BY_LABEL_KEY = "Elastic-Agent-Created-By";

src/main/java/cd/go/contrib/elasticagents/docker/DockerContainer.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ public static DockerContainer fromContainerInfo(ContainerInfo container) {
9595
return new DockerContainer(container.id(), container.name().substring(1), jobIdentifier(container), container.created(), GSON.fromJson(labels.get(Constants.CONFIGURATION_LABEL_KEY), HashMap.class), labels.get(Constants.ENVIRONMENT_LABEL_KEY));
9696
}
9797

98-
public static DockerContainer create(CreateAgentRequest request, PluginSettings settings, DockerClient docker) throws InterruptedException, DockerException {
98+
public static DockerContainer create(CreateAgentRequest request, PluginSettings settings, DockerClient docker,
99+
ConsoleLogAppender consoleLogAppender) throws InterruptedException, DockerException {
99100
String containerName = UUID.randomUUID().toString();
100101

101102
HashMap<String, String> labels = labelsFrom(request);
@@ -105,10 +106,12 @@ public static DockerContainer create(CreateAgentRequest request, PluginSettings
105106
try {
106107
docker.inspectImage(imageName);
107108
if (settings.pullOnContainerCreate()) {
109+
consoleLogAppender.accept("Pulling a fresh version of " + imageName + ".");
108110
LOG.info("Pulling a fresh version of " + imageName + ".");
109111
docker.pull(imageName);
110112
}
111113
} catch (ImageNotFoundException ex) {
114+
consoleLogAppender.accept("Image " + imageName + " not found, attempting to download.");
112115
LOG.info("Image " + imageName + " not found, attempting to download.");
113116
docker.pull(imageName);
114117
}
@@ -147,13 +150,16 @@ public static DockerContainer create(CreateAgentRequest request, PluginSettings
147150
.hostConfig(hostBuilder.build())
148151
.build();
149152

153+
consoleLogAppender.accept(String.format("Creating container: %s", containerName));
150154
ContainerCreation container = docker.createContainer(containerConfig, containerName);
151155
String id = container.id();
152156

153157
ContainerInfo containerInfo = docker.inspectContainer(id);
154158

155159
LOG.debug("Created container " + containerName);
160+
consoleLogAppender.accept(String.format("Starting container: %s", containerName));
156161
docker.startContainer(containerName);
162+
consoleLogAppender.accept(String.format("Started container: %s", containerName));
157163
LOG.debug("container " + containerName + " started");
158164
return new DockerContainer(id, containerName, request.jobIdentifier(), containerInfo.created(), request.properties(), request.environment());
159165
}
@@ -288,5 +294,4 @@ private String readLogs(DockerClient dockerClient) {
288294
return "";
289295
}
290296
}
291-
292297
}

src/main/java/cd/go/contrib/elasticagents/docker/DockerContainers.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public class DockerContainers implements AgentInstances<DockerContainer> {
4646
final Semaphore semaphore = new Semaphore(0, true);
4747

4848
@Override
49-
public DockerContainer create(CreateAgentRequest request, PluginRequest pluginRequest) throws Exception {
49+
public DockerContainer create(CreateAgentRequest request, PluginRequest pluginRequest, ConsoleLogAppender consoleLogAppender) throws Exception {
5050
LOG.info(String.format("[Create Agent] Processing create agent request for %s", request.jobIdentifier()));
5151
ClusterProfileProperties settings = request.getClusterProfileProperties();
5252
final Integer maxAllowedContainers = settings.getMaxDockerContainers();
@@ -58,7 +58,7 @@ public DockerContainer create(CreateAgentRequest request, PluginRequest pluginRe
5858
List<Map<String, String>> messages = new ArrayList<>();
5959
if (semaphore.tryAcquire()) {
6060
pluginRequest.addServerHealthMessage(messages);
61-
DockerContainer container = DockerContainer.create(request, settings, docker(settings));
61+
DockerContainer container = DockerContainer.create(request, settings, docker(settings), consoleLogAppender);
6262
register(container);
6363
jobsWaitingForAgentCreation.remove(request.jobIdentifier());
6464
return container;
@@ -70,6 +70,7 @@ public DockerContainer create(CreateAgentRequest request, PluginRequest pluginRe
7070
messageToBeAdded.put("message", maxLimitExceededMessage);
7171
messages.add(messageToBeAdded);
7272
pluginRequest.addServerHealthMessage(messages);
73+
consoleLogAppender.accept(maxLimitExceededMessage);
7374
LOG.info(maxLimitExceededMessage);
7475
return null;
7576
}

src/main/java/cd/go/contrib/elasticagents/docker/PluginRequest.java

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@
1717
package cd.go.contrib.elasticagents.docker;
1818

1919
import com.google.gson.Gson;
20+
import cd.go.contrib.elasticagents.docker.models.JobIdentifier;
21+
import com.google.gson.GsonBuilder;
2022
import com.thoughtworks.go.plugin.api.GoApplicationAccessor;
2123
import com.thoughtworks.go.plugin.api.request.DefaultGoApiRequest;
2224
import com.thoughtworks.go.plugin.api.response.GoApiResponse;
2325

2426
import java.util.*;
2527

28+
import static cd.go.contrib.elasticagents.docker.Constants.*;
2629
import static cd.go.contrib.elasticagents.docker.DockerPlugin.LOG;
27-
import static cd.go.contrib.elasticagents.docker.Constants.PROCESSOR_API_VERSION;
28-
import static cd.go.contrib.elasticagents.docker.Constants.PLUGIN_IDENTIFIER;
29-
3030

3131
/**
3232
* Instances of this class know how to send messages to the GoCD Server.
@@ -85,12 +85,29 @@ public void addServerHealthMessage(List<Map<String, String>> messages) {
8585

8686
request.setRequestBody(gson.toJson(messages));
8787

88-
// submit the request
8988
GoApiResponse response = accessor.submit(request);
9089

91-
// check status
9290
if (response.responseCode() != 200) {
9391
LOG.error("The server sent an unexpected status code " + response.responseCode() + " with the response body " + response.responseBody());
9492
}
9593
}
94+
95+
public void appendToConsoleLog(JobIdentifier jobIdentifier, String text) throws ServerRequestFailedException {
96+
Map<String, String> requestMap = new HashMap<>();
97+
requestMap.put("pipelineName", jobIdentifier.getPipelineName());
98+
requestMap.put("pipelineCounter", String.valueOf(jobIdentifier.getPipelineCounter()));
99+
requestMap.put("stageName", jobIdentifier.getStageName());
100+
requestMap.put("stageCounter", jobIdentifier.getStageCounter());
101+
requestMap.put("jobName", jobIdentifier.getJobName());
102+
requestMap.put("text", text);
103+
104+
DefaultGoApiRequest request = new DefaultGoApiRequest(Constants.REQUEST_SERVER_APPEND_TO_CONSOLE_LOG, CONSOLE_LOG_API_VERSION, PLUGIN_IDENTIFIER);
105+
request.setRequestBody(new GsonBuilder().create().toJson(requestMap));
106+
107+
GoApiResponse response = accessor.submit(request);
108+
109+
if (response.responseCode() != 200) {
110+
LOG.error("Failed to append console log for " + jobIdentifier.represent() + " with text: " + text);
111+
}
112+
}
96113
}

src/main/java/cd/go/contrib/elasticagents/docker/ServerRequestFailedException.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import static java.lang.String.format;
2222

23-
public class ServerRequestFailedException extends Exception {
23+
public class ServerRequestFailedException extends RuntimeException {
2424

2525
private ServerRequestFailedException(GoApiResponse response, String request) {
2626
super(format(
@@ -44,4 +44,8 @@ public static ServerRequestFailedException listAgents(GoApiResponse response) {
4444
public static ServerRequestFailedException getPluginSettings(GoApiResponse response) {
4545
return new ServerRequestFailedException(response, "get plugin settings");
4646
}
47+
48+
public static ServerRequestFailedException appendToConsoleLog(GoApiResponse response) {
49+
return new ServerRequestFailedException(response, "append to console log");
50+
}
4751
}

src/main/java/cd/go/contrib/elasticagents/docker/executors/CreateAgentRequestExecutor.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,20 @@
1616

1717
package cd.go.contrib.elasticagents.docker.executors;
1818

19-
import cd.go.contrib.elasticagents.docker.AgentInstances;
20-
import cd.go.contrib.elasticagents.docker.DockerContainer;
21-
import cd.go.contrib.elasticagents.docker.PluginRequest;
22-
import cd.go.contrib.elasticagents.docker.RequestExecutor;
19+
import cd.go.contrib.elasticagents.docker.*;
2320
import cd.go.contrib.elasticagents.docker.requests.CreateAgentRequest;
2421
import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse;
2522
import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse;
23+
import org.joda.time.LocalDate;
24+
import org.joda.time.LocalTime;
25+
import org.joda.time.format.DateTimeFormat;
26+
import org.joda.time.format.DateTimeFormatter;
27+
import org.joda.time.format.DateTimeFormatterBuilder;
28+
29+
import java.util.Date;
2630

2731
public class CreateAgentRequestExecutor implements RequestExecutor {
32+
private static final DateTimeFormatter MESSAGE_PREFIX_FORMATTER = DateTimeFormat.forPattern("'##|'HH:mm:ss.SSS '[go]'");
2833
private final AgentInstances<DockerContainer> agentInstances;
2934
private final PluginRequest pluginRequest;
3035
private final CreateAgentRequest request;
@@ -37,7 +42,20 @@ public CreateAgentRequestExecutor(CreateAgentRequest request, AgentInstances<Doc
3742

3843
@Override
3944
public GoPluginApiResponse execute() throws Exception {
40-
agentInstances.create(request, pluginRequest);
45+
ConsoleLogAppender consoleLogAppender = text -> {
46+
final String message = String.format("%s %s\n", LocalTime.now().toString(MESSAGE_PREFIX_FORMATTER), text);
47+
pluginRequest.appendToConsoleLog(request.jobIdentifier(), message);
48+
};
49+
50+
consoleLogAppender.accept(String.format("Received request to create a container of %s", request.dockerImage()));
51+
52+
try {
53+
agentInstances.create(request, pluginRequest, consoleLogAppender);
54+
} catch (Exception e) {
55+
consoleLogAppender.accept(String.format("Failed while creating container: %s", e.getMessage()));
56+
throw e;
57+
}
58+
4159
return new DefaultGoPluginApiResponse(200);
4260
}
4361

src/main/java/cd/go/contrib/elasticagents/docker/requests/CreateAgentRequest.java

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,9 @@
2323
import com.google.gson.Gson;
2424
import com.google.gson.GsonBuilder;
2525

26-
import java.io.IOException;
27-
import java.io.StringWriter;
2826
import java.util.ArrayList;
2927
import java.util.Collection;
3028
import java.util.Map;
31-
import java.util.Properties;
3229

3330
import static org.apache.commons.lang.StringUtils.isNotBlank;
3431

@@ -59,7 +56,7 @@ public CreateAgentRequest(String autoRegisterKey, Map<String, String> elasticAge
5956
this.clusterProfileProperties = clusterProfileProperties;
6057
}
6158

62-
public String autoRegisterKey() {
59+
String autoRegisterKey() {
6360
return autoRegisterKey;
6461
}
6562

@@ -87,37 +84,6 @@ public RequestExecutor executor(AgentInstances<DockerContainer> agentInstances,
8784
return new CreateAgentRequestExecutor(this, agentInstances, pluginRequest);
8885
}
8986

90-
public Properties autoregisterProperties(String elasticAgentId) {
91-
Properties properties = new Properties();
92-
93-
if (isNotBlank(autoRegisterKey)) {
94-
properties.put("agent.auto.register.key", autoRegisterKey);
95-
}
96-
97-
if (isNotBlank(environment)) {
98-
properties.put("agent.auto.register.environments", environment);
99-
}
100-
101-
properties.put("agent.auto.register.elasticAgent.agentId", elasticAgentId);
102-
properties.put("agent.auto.register.elasticAgent.pluginId", Constants.PLUGIN_ID);
103-
104-
return properties;
105-
}
106-
107-
public String autoregisterPropertiesAsString(String elasticAgentId) {
108-
Properties properties = autoregisterProperties(elasticAgentId);
109-
110-
StringWriter writer = new StringWriter();
111-
112-
try {
113-
properties.store(writer, "");
114-
} catch (IOException e) {
115-
throw new RuntimeException(e);
116-
}
117-
118-
return writer.toString();
119-
}
120-
12187
public Collection<String> autoregisterPropertiesAsEnvironmentVars(String elasticAgentId) {
12288
ArrayList<String> vars = new ArrayList<>();
12389
if (isNotBlank(autoRegisterKey)) {
@@ -130,4 +96,8 @@ public Collection<String> autoregisterPropertiesAsEnvironmentVars(String elastic
13096
vars.add("GO_EA_AUTO_REGISTER_ELASTIC_PLUGIN_ID=" + Constants.PLUGIN_ID);
13197
return vars;
13298
}
99+
100+
public String dockerImage() {
101+
return properties().get("Image");
102+
}
133103
}

0 commit comments

Comments
 (0)