summaryrefslogtreecommitdiffstats
path: root/configserver
diff options
context:
space:
mode:
authorHarald Musum <musum@oath.com>2018-04-12 13:12:49 +0200
committerGitHub <noreply@github.com>2018-04-12 13:12:49 +0200
commit787d8e243f59c1c93a9de4edb7f8e8852e5f6ccf (patch)
treeda1ef98a1b7ffb1edacd9f12457645f306183bae /configserver
parenteac5237fb03725d42556f1a54558411a5ee178ab (diff)
Revert "Return empty string from grabLog()"
Diffstat (limited to 'configserver')
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java14
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/LogServerLogGrabber.java94
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java3
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java32
4 files changed, 132 insertions, 11 deletions
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
index 6aba6d12751..2443e56b2d9 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
@@ -26,6 +26,7 @@ import com.yahoo.vespa.config.server.application.ApplicationConvergenceChecker;
import com.yahoo.vespa.config.server.application.ApplicationSet;
import com.yahoo.vespa.config.server.application.FileDistributionStatus;
import com.yahoo.vespa.config.server.application.HttpProxy;
+import com.yahoo.vespa.config.server.application.LogServerLogGrabber;
import com.yahoo.vespa.config.server.application.TenantApplications;
import com.yahoo.vespa.config.server.configchange.ConfigChangeActions;
import com.yahoo.vespa.config.server.configchange.RefeedActions;
@@ -79,6 +80,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
private final Tenants tenants;
private final Optional<Provisioner> hostProvisioner;
+ private final LogServerLogGrabber logServerLogGrabber;
private final ApplicationConvergenceChecker convergeChecker;
private final HttpProxy httpProxy;
private final Clock clock;
@@ -90,10 +92,11 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
@Inject
public ApplicationRepository(Tenants tenants,
HostProvisionerProvider hostProvisionerProvider,
+ LogServerLogGrabber logServerLogGrabber,
ApplicationConvergenceChecker applicationConvergenceChecker,
HttpProxy httpProxy,
ConfigserverConfig configserverConfig) {
- this(tenants, hostProvisionerProvider.getHostProvisioner(),
+ this(tenants, hostProvisionerProvider.getHostProvisioner(), logServerLogGrabber,
applicationConvergenceChecker, httpProxy, configserverConfig, Clock.systemUTC(), new FileDistributionStatus());
}
@@ -101,13 +104,14 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
public ApplicationRepository(Tenants tenants,
Provisioner hostProvisioner,
Clock clock) {
- this(tenants, Optional.of(hostProvisioner),
+ this(tenants, Optional.of(hostProvisioner), new LogServerLogGrabber(),
new ApplicationConvergenceChecker(), new HttpProxy(new SimpleHttpFetcher()),
new ConfigserverConfig(new ConfigserverConfig.Builder()), clock, new FileDistributionStatus());
}
private ApplicationRepository(Tenants tenants,
Optional<Provisioner> hostProvisioner,
+ LogServerLogGrabber logServerLogGrabber,
ApplicationConvergenceChecker applicationConvergenceChecker,
HttpProxy httpProxy,
ConfigserverConfig configserverConfig,
@@ -115,6 +119,7 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
FileDistributionStatus fileDistributionStatus) {
this.tenants = tenants;
this.hostProvisioner = hostProvisioner;
+ this.logServerLogGrabber = logServerLogGrabber;
this.convergeChecker = applicationConvergenceChecker;
this.httpProxy = httpProxy;
this.clock = clock;
@@ -212,6 +217,11 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
return true;
}
+ public String grabLog(Tenant tenant, ApplicationId applicationId) {
+ Application application = getApplication(tenant, applicationId);
+ return logServerLogGrabber.grabLog(application);
+ }
+
public HttpResponse serviceConvergenceCheck(Tenant tenant, ApplicationId applicationId, String hostname, URI uri) {
Application application = getApplication(tenant, applicationId);
return convergeChecker.serviceConvergenceCheck(application, hostname, uri);
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/LogServerLogGrabber.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/LogServerLogGrabber.java
new file mode 100644
index 00000000000..b29953187e5
--- /dev/null
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/LogServerLogGrabber.java
@@ -0,0 +1,94 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.config.server.application;
+
+import com.yahoo.component.AbstractComponent;
+import com.yahoo.config.model.api.PortInfo;
+import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.log.LogLevel;
+import com.yahoo.vespa.config.server.http.InternalServerException;
+import com.yahoo.yolean.Exceptions;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Fetches log entries from logserver with level errors and fatal. The logserver only returns
+ * a log entry once over this API so doing repeated calls will not give the same results.
+ *
+ * @author dybis
+ */
+public class LogServerLogGrabber extends AbstractComponent {
+ private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogServerLogGrabber.class.getName());
+
+ public LogServerLogGrabber() {}
+
+ public String grabLog(Application application) {
+ LogServerInfo logServerConnectionInfo = findLogserverConnectionInfo(application);
+ log.log(LogLevel.DEBUG, "Requested error logs, pulling from logserver on " + logServerConnectionInfo);
+ try {
+ return readLog(logServerConnectionInfo.hostName, logServerConnectionInfo.port);
+ } catch (IOException e) {
+ throw new InternalServerException(Exceptions.toMessageString(e));
+ }
+ }
+
+ private LogServerInfo findLogserverConnectionInfo(Application application) {
+ List<LogServerInfo> logServerConnectionInfos = new ArrayList<>();
+ application.getModel().getHosts()
+ .forEach(host -> host.getServices().stream()
+ .filter(service -> service.getServiceType().equals("logserver"))
+ .forEach(logService -> {
+ Optional<Integer> logPort = getErrorLogPort(logService);
+ logPort.ifPresent(port -> logServerConnectionInfos.add(new LogServerInfo(host.getHostname(), port)));
+ }));
+
+ if (logServerConnectionInfos.size() > 1) throw new RuntimeException("Found several log server ports");
+ if (logServerConnectionInfos.size() == 0) throw new InternalServerException("Did not find any log server in config model");
+
+ return logServerConnectionInfos.get(0);
+ }
+
+ // Protected to be able to test
+ protected String readLog(String host, int port) throws IOException {
+ Socket socket = new Socket(host, port);
+ BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ StringBuilder data = new StringBuilder();
+
+ int bufferSize = 4096;
+ int charsRead;
+ do {
+ char[] buffer = new char[bufferSize];
+ charsRead = in.read(buffer);
+ data.append(new String(buffer, 0, charsRead));
+ } while (charsRead == bufferSize);
+ in.close();
+ socket.close();
+ return data.toString();
+ }
+
+ private Optional<Integer> getErrorLogPort(ServiceInfo service) {
+ return service.getPorts().stream()
+ .filter(port -> port.getTags().contains("last-errors-holder"))
+ .map(PortInfo::getPort)
+ .findFirst();
+ }
+
+ private class LogServerInfo {
+ String hostName;
+ int port;
+
+ LogServerInfo(String hostName, int port) {
+ this.hostName = hostName;
+ this.port = port;
+ }
+
+ public String toString() {
+ return hostName + ":" + port;
+ }
+ }
+}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java
index 5bcf5da3e90..7be7bfb47e1 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandler.java
@@ -120,12 +120,11 @@ public class ApplicationHandler extends HttpHandler {
return new JSONResponse(Response.Status.OK); // return empty
}
- // TODO: Deprecated, will soon be removed, will always return empty string in payload
private HttpResponse grabLog(HttpRequest request, ApplicationId applicationId, Tenant tenant) {
if (getBindingMatch(request).groupCount() != 7)
throw new NotFoundException("Illegal POST log request '" + request.getUri() +
"': Must have 6 arguments but had " + ( getBindingMatch(request).groupCount()-1 ) );
- final String response = "";
+ final String response = applicationRepository.grabLog(tenant, applicationId);
return new HttpResponse(200) {
@Override
public void render(OutputStream outputStream) throws IOException {
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java
index e5f2cc271e3..ef53baf821d 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/ApplicationHandlerTest.java
@@ -22,6 +22,7 @@ import com.yahoo.vespa.config.server.SuperModelGenerationCounter;
import com.yahoo.vespa.config.server.TestComponentRegistry;
import com.yahoo.vespa.config.server.application.ApplicationConvergenceChecker;
import com.yahoo.vespa.config.server.application.HttpProxy;
+import com.yahoo.vespa.config.server.application.LogServerLogGrabber;
import com.yahoo.vespa.config.server.http.HandlerTest;
import com.yahoo.vespa.config.server.http.HttpErrorResponse;
import com.yahoo.vespa.config.server.http.StaticResponse;
@@ -86,20 +87,27 @@ public class ApplicationHandlerTest {
tenants = testBuilder.createTenants();
provisioner = new SessionHandlerTest.MockProvisioner();
- mockHandler = createApplicationHandler(provisioner, new ApplicationConvergenceChecker(stateApiFactory), mockHttpProxy);
+ mockHandler = createMockApplicationHandler(
+ provisioner,
+ new ApplicationConvergenceChecker(stateApiFactory),
+ mockHttpProxy,
+ new MockLogServerLogGrabber());
listApplicationsHandler = new ListApplicationsHandler(
ListApplicationsHandler.testOnlyContext(),
tenants, Zone.defaultZone());
}
- private ApplicationHandler createApplicationHandler(Provisioner provisioner,
- ApplicationConvergenceChecker convergeChecker,
- HttpProxy httpProxy) {
+ private ApplicationHandler createMockApplicationHandler(
+ Provisioner provisioner,
+ ApplicationConvergenceChecker convergeChecker,
+ HttpProxy httpProxy,
+ LogServerLogGrabber logServerLogGrabber) {
return new ApplicationHandler(
ApplicationHandler.testOnlyContext(),
Zone.defaultZone(),
new ApplicationRepository(tenants,
HostProvisionerProvider.withProvisioner(provisioner),
+ logServerLogGrabber,
convergeChecker,
httpProxy,
new ConfigserverConfig(new ConfigserverConfig.Builder())));
@@ -111,6 +119,7 @@ public class ApplicationHandlerTest {
Zone.defaultZone(),
new ApplicationRepository(tenants,
HostProvisionerProvider.withProvisioner(provisioner),
+ new LogServerLogGrabber(),
new ApplicationConvergenceChecker(stateApiFactory),
new HttpProxy(new SimpleHttpFetcher()),
new ConfigserverConfig(new ConfigserverConfig.Builder())));
@@ -205,13 +214,12 @@ public class ApplicationHandlerTest {
converge(application, Zone.defaultZone());
}
- // TODO: Deprecated, will soon be removed, implementation always returns empty string
@Test
public void testGrabLog() throws Exception {
long sessionId = 1;
ApplicationId application = new ApplicationId.Builder().applicationName(ApplicationName.defaultName()).tenant(mytenantName).build();
addMockApplication(tenants.getTenant(mytenantName), application, sessionId, Clock.systemUTC());
- assertEquals("", grabLog(application, Zone.defaultZone()));
+ assertEquals("log line", grabLog(application, Zone.defaultZone()));
}
@Test
@@ -238,7 +246,11 @@ public class ApplicationHandlerTest {
@Ignore
public void testFailingProvisioner() throws Exception {
provisioner = new SessionHandlerTest.FailingMockProvisioner();
- mockHandler = createApplicationHandler(provisioner, new ApplicationConvergenceChecker(stateApiFactory), new HttpProxy(new SimpleHttpFetcher()));
+ mockHandler = createMockApplicationHandler(
+ provisioner,
+ new ApplicationConvergenceChecker(stateApiFactory),
+ new HttpProxy(new SimpleHttpFetcher()),
+ new LogServerLogGrabber());
final ApplicationId applicationId = ApplicationId.defaultId();
addMockApplication(tenants.getTenant(mytenantName), applicationId, 1, Clock.systemUTC());
assertApplicationExists(mytenantName, applicationId, Zone.defaultZone());
@@ -420,4 +432,10 @@ public class ApplicationHandlerTest {
}
}
+ private static class MockLogServerLogGrabber extends LogServerLogGrabber {
+ @Override
+ protected String readLog(String host, int port) throws IOException {
+ return "log line";
+ }
+ }
}