summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java49
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterInfo.java30
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterMetricsRetriever.java80
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/metrics/MetricsRetriever.java10
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/metrics/MetricsRetrieverTest.java4
5 files changed, 64 insertions, 109 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 c165705dc8c..c8b99e2c3a0 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
@@ -44,7 +44,9 @@ import com.yahoo.vespa.config.server.http.LogRetriever;
import com.yahoo.vespa.config.server.http.SimpleHttpFetcher;
import com.yahoo.vespa.config.server.http.v2.MetricsResponse;
import com.yahoo.vespa.config.server.http.v2.PrepareResult;
-import com.yahoo.vespa.config.server.metrics.ClusterMetricsRetriever;
+import com.yahoo.vespa.config.server.metrics.ClusterInfo;
+import com.yahoo.vespa.config.server.metrics.MetricsAggregator;
+import com.yahoo.vespa.config.server.metrics.MetricsRetriever;
import com.yahoo.vespa.config.server.provision.HostProvisionerProvider;
import com.yahoo.vespa.config.server.session.LocalSession;
import com.yahoo.vespa.config.server.session.LocalSessionRepo;
@@ -71,8 +73,11 @@ import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
@@ -82,6 +87,7 @@ import java.util.stream.Collectors;
import static com.yahoo.config.model.api.container.ContainerServiceType.CLUSTERCONTROLLER_CONTAINER;
import static com.yahoo.config.model.api.container.ContainerServiceType.CONTAINER;
import static com.yahoo.config.model.api.container.ContainerServiceType.LOGSERVER_CONTAINER;
+import static com.yahoo.config.model.api.container.ContainerServiceType.METRICS_PROXY_CONTAINER;
import static com.yahoo.vespa.config.server.tenant.TenantRepository.HOSTED_VESPA_TENANT;
import static java.nio.file.Files.readAttributes;
@@ -643,8 +649,16 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
// ---------------- Metrics ------------------------------------------------------------------------
public MetricsResponse getMetrics(ApplicationId applicationId) {
- Application application = getApplication(applicationId);
- return ClusterMetricsRetriever.getMetrics(application);
+ var metricsRetriever = new MetricsRetriever();
+ var clusters = getClustersOfApplication(applicationId);
+ var clusterMetrics = new LinkedHashMap<ClusterInfo, MetricsAggregator>();
+
+ clusters.forEach(cluster -> {
+ var metrics = metricsRetriever.requestMetricsForCluster(cluster);
+ clusterMetrics.put(cluster, metrics);
+ });
+
+ return new MetricsResponse(200, applicationId, clusterMetrics);
}
// ---------------- Misc operations ----------------------------------------------------------------
@@ -778,6 +792,35 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
return port;
}
+ /** Finds the hosts of an application, grouped by cluster name */
+ private Collection<ClusterInfo> getClustersOfApplication(ApplicationId applicationId) {
+ Application application = getApplication(applicationId);
+ Map<String, ClusterInfo> clusters = new HashMap<>();
+ application.getModel().getHosts().stream()
+ .filter(host -> host.getServices().stream().noneMatch(serviceInfo -> serviceInfo.getServiceType().equalsIgnoreCase("logserver")))
+ .forEach(hostInfo -> {
+ ServiceInfo metricsService = getServiceInfoByType(hostInfo, METRICS_PROXY_CONTAINER.serviceName);
+ ServiceInfo clusterServiceInfo = getServiceInfoByType(hostInfo, "container", "searchnode");
+ ClusterInfo clusterInfo = createClusterInfo(clusterServiceInfo);
+ URI host = URI.create("http://" + hostInfo.getHostname() + ":" + servicePort(metricsService) + "/metrics/v1/values?consumer=Vespa");
+ clusters.computeIfAbsent(clusterInfo.getClusterId(), c -> clusterInfo).addHost(host);
+ }
+ );
+ return clusters.values();
+
+ }
+
+ private ServiceInfo getServiceInfoByType(HostInfo hostInfo, String... types) {
+ List<String> type = List.of(types);
+ return hostInfo.getServices().stream().filter(serviceInfo -> type.contains(serviceInfo.getServiceType())).findFirst().orElseThrow();
+ }
+
+ private ClusterInfo createClusterInfo(ServiceInfo serviceInfo) {
+ String clusterName = serviceInfo.getServiceName();
+ ClusterInfo.ClusterType clusterType = serviceInfo.getServiceType().equals("searchnode") ? ClusterInfo.ClusterType.content : ClusterInfo.ClusterType.container;
+ return new ClusterInfo(clusterName, clusterType);
+ }
+
/** Returns version to use when deploying application in given environment */
static Version decideVersion(ApplicationId application, Environment environment, Version sessionVersion, boolean bootstrap) {
if ( environment.isManuallyDeployed()
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterInfo.java b/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterInfo.java
index bd453dddd74..7507b5c4c2c 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterInfo.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterInfo.java
@@ -1,22 +1,15 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.config.server.metrics;
-import com.yahoo.config.model.api.ServiceInfo;
-
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
-import java.util.Optional;
-import java.util.Set;
/**
* @author olaa
*/
public class ClusterInfo {
- private static final Set<String> CONTENT_SERVICES = Set.of("storagenode", "searchnode", "distributor", "container-clustercontroller");
- private static final Set<String> CONTAINER_SERVICES = Set.of("qrserver", "container");
-
private final String clusterId;
private final ClusterType clusterType;
private final List<URI> hostnames;
@@ -47,18 +40,17 @@ public class ClusterInfo {
hostnames.add(host);
}
- // Try to determine whether host is content or container based on service
- public static Optional<ClusterInfo> fromServiceInfo(ServiceInfo serviceInfo) {
- String serviceType = serviceInfo.getServiceType();
- ClusterType clusterType;
- if (CONTENT_SERVICES.contains(serviceType)) clusterType = ClusterType.content;
- else if (CONTAINER_SERVICES.contains(serviceType)) clusterType = ClusterType.container;
- else return Optional.empty();
- return Optional.of(new ClusterInfo(serviceInfo.getServiceName(), clusterType));
- }
-
public enum ClusterType {
content,
- container
- }
+ container;
+
+ public static boolean isValidType(String enumString) {
+ try {
+ valueOf(enumString);
+ return true;
+ } catch (IllegalArgumentException e) {
+ return false;
+ }
+ }
+ };
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterMetricsRetriever.java b/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterMetricsRetriever.java
deleted file mode 100644
index 50d5dd41d9c..00000000000
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/ClusterMetricsRetriever.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.config.server.metrics;
-
-import com.yahoo.config.model.api.HostInfo;
-import com.yahoo.config.model.api.ServiceInfo;
-import com.yahoo.vespa.config.server.application.Application;
-import com.yahoo.vespa.config.server.http.v2.MetricsResponse;
-import com.yahoo.vespa.model.admin.metricsproxy.MetricsProxyContainer;
-
-import java.net.URI;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ForkJoinPool;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Predicate;
-
-/**
- * @author olaa
- *
- * Retrieves metrics for given application, grouped by cluster
- */
-public class ClusterMetricsRetriever {
-
- public static MetricsResponse getMetrics(Application application) {
- var clusters = getClustersOfApplication(application);
- var clusterMetrics = new ConcurrentHashMap<ClusterInfo, MetricsAggregator>();
-
- Runnable retrieveMetricsJob = () ->
- clusters.parallelStream().forEach(cluster -> {
- MetricsAggregator metrics = MetricsRetriever.requestMetricsForCluster(cluster);
- clusterMetrics.put(cluster, metrics);
- });
-
- ForkJoinPool threadPool = new ForkJoinPool(5);
- threadPool.submit(retrieveMetricsJob);
- threadPool.shutdown();
-
- try {
- threadPool.awaitTermination(1, TimeUnit.MINUTES);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
-
- return new MetricsResponse(200, application.getId(), clusterMetrics);
- }
-
- /** Finds the hosts of an application, grouped by cluster name */
- private static Collection<ClusterInfo> getClustersOfApplication(Application application) {
- Map<String, ClusterInfo> clusters = new HashMap<>();
-
- application.getModel().getHosts().stream()
- .filter(host -> host.getServices().stream().noneMatch(isLogserver()))
- .forEach(hostInfo -> {
- ClusterInfo clusterInfo = createClusterInfo(hostInfo);
- URI metricsProxyURI = createMetricsProxyURI(hostInfo.getHostname());
- clusters.computeIfAbsent(clusterInfo.getClusterId(), c -> clusterInfo).addHost(metricsProxyURI);
- }
- );
- return clusters.values();
-
- }
-
- private static Predicate<ServiceInfo> isLogserver() {
- return serviceInfo -> serviceInfo.getServiceType().equalsIgnoreCase("logserver");
- }
-
- private static URI createMetricsProxyURI(String hostname) {
- return URI.create("http://" + hostname + ":" + MetricsProxyContainer.BASEPORT + "/metrics/v1/values?consumer=Vespa");
- }
-
- private static ClusterInfo createClusterInfo(HostInfo hostInfo) {
- return hostInfo.getServices().stream()
- .map(ClusterInfo::fromServiceInfo)
- .filter(Optional::isPresent)
- .findFirst().get().orElseThrow();
- }
-}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/MetricsRetriever.java b/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/MetricsRetriever.java
index 8a18843db5f..4fbeae11758 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/MetricsRetriever.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/metrics/MetricsRetriever.java
@@ -27,18 +27,19 @@ import java.util.logging.Logger;
*/
public class MetricsRetriever {
private static final Logger log = Logger.getLogger(MetricsRetriever.class.getName());
+ private final HttpClient httpClient = HttpClientBuilder.create().build();
/**
* Call the metrics API on each host in the cluster and aggregate the metrics
* into a single value.
*/
- public static MetricsAggregator requestMetricsForCluster(ClusterInfo clusterInfo) {
+ public MetricsAggregator requestMetricsForCluster(ClusterInfo clusterInfo) {
var aggregator = new MetricsAggregator();
clusterInfo.getHostnames().forEach(host -> getHostMetrics(host, aggregator));
return aggregator;
}
- private static void getHostMetrics(URI hostURI, MetricsAggregator metrics) {
+ private void getHostMetrics(URI hostURI, MetricsAggregator metrics) {
Slime responseBody = doMetricsRequest(hostURI);
var parseError = responseBody.get().field("error_message");
@@ -52,10 +53,9 @@ public class MetricsRetriever {
});
}
- private static Slime doMetricsRequest(URI hostURI) {
+ private Slime doMetricsRequest(URI hostURI) {
HttpGet get = new HttpGet(hostURI);
try {
- HttpClient httpClient = HttpClientBuilder.create().build();
HttpResponse response = httpClient.execute(get);
InputStream is = response.getEntity().getContent();
Slime slime = SlimeUtils.jsonToSlime(is.readAllBytes());
@@ -66,7 +66,7 @@ public class MetricsRetriever {
}
}
- private static void parseService(Inspector service, MetricsAggregator metrics) {
+ private void parseService(Inspector service, MetricsAggregator metrics) {
String serviceName = service.field("name").asString();
Instant timestamp = Instant.ofEpochSecond(service.field("timestamp").asLong());
metrics.setTimestamp(timestamp);
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/MetricsRetrieverTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/MetricsRetrieverTest.java
index 67e91b90803..1b878a432c9 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/MetricsRetrieverTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/metrics/MetricsRetrieverTest.java
@@ -55,7 +55,7 @@ public class MetricsRetrieverTest {
compareAggregators(
new MetricsAggregator().addDocumentCount(6000.0),
- MetricsRetriever.requestMetricsForCluster(clusters.get(0))
+ metricsRetriever.requestMetricsForCluster(clusters.get(0))
);
compareAggregators(
@@ -64,7 +64,7 @@ public class MetricsRetrieverTest {
.addContainerLatency(2000, 0)
.addQrLatency(3000, 43)
.addFeedLatency(3000, 43),
- MetricsRetriever.requestMetricsForCluster(clusters.get(1))
+ metricsRetriever.requestMetricsForCluster(clusters.get(1))
);
wireMock.stop();