Skip to content

Commit 71c1970

Browse files
authored
Merge pull request #136 from varshavaradarajan/append-to-console-log
Show plugin messages in job console log
2 parents fe7cc91 + 5343d5b commit 71c1970

12 files changed

+198
-52
lines changed

src/main/java/cd/go/contrib/elasticagent/AgentInstances.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ public interface AgentInstances<T> {
3131
* <p>
3232
* So that instances created are auto-registered with the server, the agent instance MUST have an
3333
* <code>autoregister.properties</code> file.
34-
* @param request the request object
34+
* @param request the request object
3535
* @param settings   the plugin settings object
3636
* @param pluginRequest the plugin request object
37+
* @param consoleLogAppender
3738
*/
38-
T create(CreateAgentRequest request, PluginSettings settings, PluginRequest pluginRequest) throws Exception;
39+
T create(CreateAgentRequest request, PluginSettings settings, PluginRequest pluginRequest, ConsoleLogAppender consoleLogAppender) throws Exception;
3940

4041
/**
4142
* This message is sent when the plugin needs to terminate the agent instance.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2019 ThoughtWorks, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package cd.go.contrib.elasticagent;
18+
19+
import java.util.function.Consumer;
20+
21+
public interface ConsoleLogAppender extends Consumer<String> {
22+
}

src/main/java/cd/go/contrib/elasticagent/Constants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public interface Constants {
3131
String PROCESSOR_API_VERSION = "1.0";
3232
String EXTENSION_API_VERSION = "5.0";
3333
String SERVER_INFO_API_VERSION = "1.0";
34+
String CONSOLE_LOG_API_VERSION = "1.0";
3435

3536
// the identifier of this plugin
3637
GoPluginIdentifier PLUGIN_IDENTIFIER = new GoPluginIdentifier(EXTENSION_TYPE, Collections.singletonList(EXTENSION_API_VERSION));
@@ -41,6 +42,7 @@ public interface Constants {
4142
String REQUEST_SERVER_DELETE_AGENT = REQUEST_SERVER_PREFIX + ".elastic-agents.delete-agents";
4243
String REQUEST_SERVER_LIST_AGENTS = REQUEST_SERVER_PREFIX + ".elastic-agents.list-agents";
4344
String REQUEST_SERVER_INFO = REQUEST_SERVER_PREFIX + ".server-info.get";
45+
String REQUEST_SERVER_APPEND_TO_CONSOLE_LOG = REQUEST_SERVER_PREFIX + ".console-log.append";
4446

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

src/main/java/cd/go/contrib/elasticagent/KubernetesAgentInstances.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,18 @@ public KubernetesAgentInstances(KubernetesClientFactory factory, KubernetesInsta
5858
}
5959

6060
@Override
61-
public KubernetesInstance create(CreateAgentRequest request, PluginSettings settings, PluginRequest pluginRequest) {
61+
public KubernetesInstance create(CreateAgentRequest request, PluginSettings settings, PluginRequest pluginRequest, ConsoleLogAppender consoleLogAppender) {
6262
final Integer maxAllowedContainers = settings.getMaxPendingPods();
6363
synchronized (instances) {
6464
refreshAll(settings);
6565
doWithLockOnSemaphore(new SetupSemaphore(maxAllowedContainers, instances, semaphore));
66-
66+
consoleLogAppender.accept("Waiting to create agent pod.");
6767
if (semaphore.tryAcquire()) {
68-
return createKubernetesInstance(request, settings, pluginRequest);
68+
return createKubernetesInstance(request, settings, pluginRequest, consoleLogAppender);
6969
} else {
70-
LOG.warn(format("Create Agent Request] The number of pending kubernetes pods is currently at the maximum permissible limit ({0}). Total kubernetes pods ({1}). Not creating any more containers.", maxAllowedContainers, instances.size()));
70+
String message = format("[Create Agent Request] The number of pending kubernetes pods is currently at the maximum permissible limit ({0}). Total kubernetes pods ({1}). Not creating any more containers.", maxAllowedContainers, instances.size());
71+
LOG.warn(message);
72+
consoleLogAppender.accept(message);
7173
return null;
7274
}
7375
}
@@ -79,16 +81,20 @@ private void doWithLockOnSemaphore(Runnable runnable) {
7981
}
8082
}
8183

82-
private KubernetesInstance createKubernetesInstance(CreateAgentRequest request, PluginSettings settings, PluginRequest pluginRequest) {
84+
private KubernetesInstance createKubernetesInstance(CreateAgentRequest request, PluginSettings settings, PluginRequest pluginRequest, ConsoleLogAppender consoleLogAppender) {
8385
JobIdentifier jobIdentifier = request.jobIdentifier();
8486
if (isAgentCreatedForJob(jobIdentifier.getJobId())) {
85-
LOG.warn(format("[Create Agent Request] Request for creating an agent for Job Identifier [{0}] has already been scheduled. Skipping current request.", jobIdentifier));
87+
String message = format("[Create Agent Request] Request for creating an agent for Job Identifier [{0}] has already been scheduled. Skipping current request.", jobIdentifier);
88+
LOG.warn(message);
89+
consoleLogAppender.accept(message);
8690
return null;
8791
}
8892

8993
KubernetesClient client = factory.client(settings);
9094
KubernetesInstance instance = kubernetesInstanceFactory.create(request, settings, client, pluginRequest);
95+
consoleLogAppender.accept(format("Creating pod: %s", instance.name()));
9196
register(instance);
97+
consoleLogAppender.accept(format("Agent pod %s created. Waiting for it to register to the GoCD server.", instance.name()));
9298

9399
return instance;
94100
}

src/main/java/cd/go/contrib/elasticagent/PluginRequest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,16 @@
1616

1717
package cd.go.contrib.elasticagent;
1818

19+
import cd.go.contrib.elasticagent.model.JobIdentifier;
1920
import cd.go.contrib.elasticagent.model.ServerInfo;
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.Collection;
27+
import java.util.HashMap;
28+
import java.util.Map;
2529

2630
import static cd.go.contrib.elasticagent.Constants.*;
2731
import static cd.go.contrib.elasticagent.KubernetesPlugin.LOG;
@@ -86,4 +90,23 @@ public void deleteAgents(Collection<Agent> toBeDeleted) throws ServerRequestFail
8690
throw ServerRequestFailedException.deleteAgents(response);
8791
}
8892
}
93+
94+
public void appendToConsoleLog(JobIdentifier jobIdentifier, String text) throws ServerRequestFailedException {
95+
Map<String, String> requestMap = new HashMap<>();
96+
requestMap.put("pipelineName", jobIdentifier.getPipelineName());
97+
requestMap.put("pipelineCounter", String.valueOf(jobIdentifier.getPipelineCounter()));
98+
requestMap.put("stageName", jobIdentifier.getStageName());
99+
requestMap.put("stageCounter", jobIdentifier.getStageCounter());
100+
requestMap.put("jobName", jobIdentifier.getJobName());
101+
requestMap.put("text", text);
102+
103+
DefaultGoApiRequest request = new DefaultGoApiRequest(Constants.REQUEST_SERVER_APPEND_TO_CONSOLE_LOG, CONSOLE_LOG_API_VERSION, PLUGIN_IDENTIFIER);
104+
request.setRequestBody(new GsonBuilder().create().toJson(requestMap));
105+
106+
GoApiResponse response = accessor.submit(request);
107+
108+
if (response.responseCode() != 200) {
109+
LOG.error("Failed to append to console log for " + jobIdentifier.getRepresentation() + " with text: " + text);
110+
}
111+
}
89112
}

src/main/java/cd/go/contrib/elasticagent/ServerRequestFailedException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,8 @@ public static ServerRequestFailedException getPluginSettings(GoApiResponse respo
4848
public static ServerRequestFailedException serverInfo(GoApiResponse response) {
4949
return new ServerRequestFailedException(response, "get server info");
5050
}
51+
52+
public static ServerRequestFailedException appendToConsoleLog(GoApiResponse response) {
53+
return new ServerRequestFailedException(response, "append to console log");
54+
}
5155
}

src/main/java/cd/go/contrib/elasticagent/executors/CreateAgentRequestExecutor.java

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

1717
package cd.go.contrib.elasticagent.executors;
1818

19-
import cd.go.contrib.elasticagent.AgentInstances;
20-
import cd.go.contrib.elasticagent.KubernetesInstance;
21-
import cd.go.contrib.elasticagent.PluginRequest;
22-
import cd.go.contrib.elasticagent.RequestExecutor;
19+
import cd.go.contrib.elasticagent.*;
2320
import cd.go.contrib.elasticagent.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.DateTime;
24+
import org.joda.time.LocalTime;
25+
import org.joda.time.format.DateTimeFormat;
26+
import org.joda.time.format.DateTimeFormatter;
2627

2728
import static cd.go.contrib.elasticagent.KubernetesPlugin.LOG;
2829
import static java.text.MessageFormat.format;
2930

3031
public class CreateAgentRequestExecutor implements RequestExecutor {
32+
private static final DateTimeFormatter MESSAGE_PREFIX_FORMATTER = DateTimeFormat.forPattern("'##|'HH:mm:ss.SSS '[go]'");
3133
private final AgentInstances<KubernetesInstance> agentInstances;
3234
private final PluginRequest pluginRequest;
3335
private final CreateAgentRequest request;
@@ -41,7 +43,18 @@ public CreateAgentRequestExecutor(CreateAgentRequest request, AgentInstances<Kub
4143
@Override
4244
public GoPluginApiResponse execute() throws Exception {
4345
LOG.debug(format("[Create Agent] creating elastic agent for profile {0} in cluster {1}", request.properties(), request.clusterProfileProperties()));
44-
agentInstances.create(request, request.clusterProfileProperties(), pluginRequest);
46+
ConsoleLogAppender consoleLogAppender = text -> {
47+
final String message = String.format("%s %s\n", LocalTime.now().toString(MESSAGE_PREFIX_FORMATTER), text);
48+
pluginRequest.appendToConsoleLog(request.jobIdentifier(), message);
49+
};
50+
consoleLogAppender.accept(format("Received request to create a pod for job {0} in cluster {1} at {2}", request.jobIdentifier(), request.clusterProfileProperties().getClusterUrl(), new DateTime().toString("yyyy-MM-dd HH:mm:ss ZZ")));
51+
try {
52+
agentInstances.create(request, request.clusterProfileProperties(), pluginRequest, consoleLogAppender);
53+
} catch (Exception e) {
54+
consoleLogAppender.accept(format("Failed to create agent pod: %s", e.getMessage()));
55+
throw e;
56+
}
57+
4558
return new DefaultGoPluginApiResponse(200);
4659
}
4760

0 commit comments

Comments
 (0)