summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java3
-rw-r--r--container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java3
-rw-r--r--container-search/src/main/java/com/yahoo/search/handler/HttpSearchResponse.java47
-rw-r--r--container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java15
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java (renamed from container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java)12
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg16
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/config/handlers.cfg12
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/config/handlers2/chains.cfg8
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/config/handlersInvalid/handlers.cfg2
9 files changed, 76 insertions, 42 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java
index 1743d5f4432..65b70bdce33 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/monitoring/VespaMetricSet.java
@@ -322,6 +322,7 @@ public class VespaMetricSet {
metrics.add(new Metric("documents_total.count"));
metrics.add(new Metric("dispatch_internal.rate"));
metrics.add(new Metric("dispatch_fdispatch.rate"));
+ addMetric(metrics, "jdisc.search.render_latency", Set.of("min", "max", "count", "sum", "last"));
metrics.add(new Metric("totalhits_per_query.max"));
metrics.add(new Metric("totalhits_per_query.sum"));
@@ -783,7 +784,7 @@ public class VespaMetricSet {
return metrics;
}
- private static void addMetric(Set<Metric> metrics, String metricName, List<String> aggregateSuffices) {
+ private static void addMetric(Set<Metric> metrics, String metricName, Iterable<String> aggregateSuffices) {
for (String suffix : aggregateSuffices) {
metrics.add(new Metric(metricName + "." + suffix));
}
diff --git a/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java b/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java
index d98a865e1fb..087be0f17c5 100644
--- a/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java
+++ b/container-core/src/main/java/com/yahoo/container/core/config/testutil/HandlersConfigurerTestWrapper.java
@@ -13,7 +13,9 @@ import com.yahoo.container.core.config.HandlersConfigurerDi;
import com.yahoo.container.di.CloudSubscriberFactory;
import com.yahoo.container.di.ComponentDeconstructor;
import com.yahoo.container.handler.threadpool.ContainerThreadPool;
+import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.handler.RequestHandler;
+import com.yahoo.jdisc.test.MockMetric;
import com.yahoo.language.Linguistics;
import com.yahoo.language.simple.SimpleLinguistics;
@@ -139,6 +141,7 @@ public class HandlersConfigurerTestWrapper {
// Needed by e.g. SearchHandler
bind(Linguistics.class).to(SimpleLinguistics.class).in(Scopes.SINGLETON);
bind(ContainerThreadPool.class).to(SimpleContainerThreadpool.class);
+ bind(Metric.class).to(MockMetric.class);
}
});
}
diff --git a/container-search/src/main/java/com/yahoo/search/handler/HttpSearchResponse.java b/container-search/src/main/java/com/yahoo/search/handler/HttpSearchResponse.java
index d636d3bc925..7ef9ebad010 100644
--- a/container-search/src/main/java/com/yahoo/search/handler/HttpSearchResponse.java
+++ b/container-search/src/main/java/com/yahoo/search/handler/HttpSearchResponse.java
@@ -1,20 +1,15 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.search.handler;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
import com.google.common.util.concurrent.ListenableFuture;
import com.yahoo.collections.ListMap;
-import com.yahoo.container.jdisc.ExtendedResponse;
import com.yahoo.container.handler.Coverage;
import com.yahoo.container.handler.Timing;
+import com.yahoo.container.jdisc.ExtendedResponse;
import com.yahoo.container.logging.AccessLogEntry;
import com.yahoo.container.logging.HitCounts;
import com.yahoo.jdisc.HeaderFields;
+import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.handler.CompletionHandler;
import com.yahoo.jdisc.handler.ContentChannel;
import com.yahoo.processing.execution.Execution.Trace.LogValue;
@@ -25,6 +20,13 @@ import com.yahoo.search.Result;
import com.yahoo.search.query.context.QueryContext;
import com.yahoo.yolean.trace.TraceNode;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.time.Duration;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
/**
* Wrap the result of a query as an HTTP response.
*
@@ -35,20 +37,21 @@ public class HttpSearchResponse extends ExtendedResponse {
private final Result result;
private final Query query;
private final Renderer<Result> rendererCopy;
+ private final Metric metric;
private final Timing timing;
private final HitCounts hitCounts;
private final TraceNode trace;
- public HttpSearchResponse(int status, Result result, Query query, Renderer renderer) {
- this(status, result, query, renderer, null);
+ public HttpSearchResponse(int status, Result result, Query query, Renderer<Result> renderer) {
+ this(status, result, query, renderer, null, null);
}
- HttpSearchResponse(int status, Result result, Query query, Renderer renderer, TraceNode trace) {
+ HttpSearchResponse(int status, Result result, Query query, Renderer<Result> renderer, TraceNode trace, Metric metric) {
super(status);
this.query = query;
this.result = result;
this.rendererCopy = renderer;
-
+ this.metric = metric;
this.timing = SearchResponse.createTiming(query, result);
this.hitCounts = SearchResponse.createHitCounts(query, result);
this.trace = trace;
@@ -98,7 +101,11 @@ public class HttpSearchResponse extends ExtendedResponse {
}
try {
try {
- waitableRender(output);
+ long nanoStart = System.nanoTime();
+ ListenableFuture<Boolean> promise = waitableRender(output);
+ if (metric != null) {
+ promise.addListener(new RendererLatencyReporter(nanoStart), Runnable::run);
+ }
} finally {
if (!(rendererCopy instanceof AsynchronousSectionedRenderer)) {
output.flush();
@@ -178,4 +185,20 @@ public class HttpSearchResponse extends ExtendedResponse {
: context::logValueIterator;
}
+ private class RendererLatencyReporter implements Runnable {
+
+ final long nanoStart;
+
+ RendererLatencyReporter(long nanoStart) { this.nanoStart = nanoStart; }
+
+ @Override
+ public void run() {
+ long latencyMillis = Duration.ofNanos(System.nanoTime() - nanoStart).toMillis();
+ Metric.Context ctx = metric.createContext(Map.of(
+ SearchHandler.RENDERER_DIMENSION, rendererCopy.getClassName(),
+ SearchHandler.MIME_DIMENSION, rendererCopy.getMimeType()));
+ metric.set(SearchHandler.RENDER_LATENCY_METRIC, latencyMillis, ctx);
+ }
+ }
+
}
diff --git a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
index e2c15b6e35b..f81aab4259d 100644
--- a/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
+++ b/container-search/src/main/java/com/yahoo/search/handler/SearchHandler.java
@@ -11,6 +11,7 @@ import com.yahoo.container.QrSearchersConfig;
import com.yahoo.container.core.ChainsConfig;
import com.yahoo.container.core.ContainerHttpConfig;
import com.yahoo.container.handler.threadpool.ContainerThreadPool;
+import com.yahoo.container.jdisc.AclMapping;
import com.yahoo.container.jdisc.HttpMethodAclMapping;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.container.jdisc.HttpResponse;
@@ -21,8 +22,6 @@ import com.yahoo.container.logging.AccessLog;
import com.yahoo.io.IOUtils;
import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.Request;
-import com.yahoo.container.jdisc.AclMapping;
-import com.yahoo.container.jdisc.RequestView;
import com.yahoo.language.Linguistics;
import com.yahoo.net.HostName;
import com.yahoo.net.UriTools;
@@ -88,6 +87,9 @@ public class SearchHandler extends LoggingRequestHandler {
/** Event name for number of connections to the search subsystem */
private static final String SEARCH_CONNECTIONS = "search_connections";
+ static final String RENDER_LATENCY_METRIC = "jdisc.search.render_latency";
+ static final String MIME_DIMENSION = "mime";
+ static final String RENDERER_DIMENSION = "renderer";
private static final String JSON_CONTENT_TYPE = "application/json";
@@ -230,6 +232,8 @@ public class SearchHandler extends LoggingRequestHandler {
new ExecutionFactory(chainsConfig, indexInfo, clusters, searchers, specialtokens, linguistics, renderers));
}
+ Metric metric() { return metric; }
+
private static int examineExecutor(Executor executor) {
if (executor instanceof ThreadPoolExecutor) {
return ((ThreadPoolExecutor) executor).getMaximumPoolSize();
@@ -273,7 +277,7 @@ public class SearchHandler extends LoggingRequestHandler {
private HttpResponse errorResponse(HttpRequest request, ErrorMessage errorMessage) {
Query query = new Query();
Result result = new Result(query, errorMessage);
- Renderer renderer = getRendererCopy(ComponentSpecification.fromString(request.getProperty("format")));
+ Renderer<Result> renderer = getRendererCopy(ComponentSpecification.fromString(request.getProperty("format")));
return new HttpSearchResponse(getHttpResponseStatus(request, result), result, query, renderer);
}
@@ -328,10 +332,11 @@ public class SearchHandler extends LoggingRequestHandler {
}
// Transform result to response
- Renderer renderer = toRendererCopy(query.getPresentation().getRenderer());
+ Renderer<Result> renderer = toRendererCopy(query.getPresentation().getRenderer());
HttpSearchResponse response = new HttpSearchResponse(getHttpResponseStatus(request, result),
result, query, renderer,
- extractTraceNode(query));
+ extractTraceNode(query),
+ metric);
response.setRequestType(Request.RequestType.READ);
hostResponseHeaderKey.ifPresent(key -> response.headers().add(key, selfHostname));
diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java
index 2eb5901b786..2b584c7b285 100644
--- a/container-search/src/test/java/com/yahoo/search/handler/test/SearchHandlerTestCase.java
+++ b/container-search/src/test/java/com/yahoo/search/handler/SearchHandlerTest.java
@@ -1,5 +1,5 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.search.handler.test;
+package com.yahoo.search.handler;
import com.yahoo.container.Container;
import com.yahoo.container.core.config.testutil.HandlersConfigurerTestWrapper;
@@ -10,12 +10,11 @@ import com.yahoo.container.jdisc.ThreadedHttpRequestHandler;
import com.yahoo.io.IOUtils;
import com.yahoo.jdisc.Request;
import com.yahoo.jdisc.handler.RequestHandler;
+import com.yahoo.jdisc.test.MockMetric;
import com.yahoo.net.HostName;
import com.yahoo.search.Query;
import com.yahoo.search.Result;
import com.yahoo.search.Searcher;
-import com.yahoo.search.handler.HttpSearchResponse;
-import com.yahoo.search.handler.SearchHandler;
import com.yahoo.search.rendering.XmlRenderer;
import com.yahoo.search.result.ErrorMessage;
import com.yahoo.search.result.Hit;
@@ -45,7 +44,7 @@ import static org.junit.Assert.assertTrue;
/**
* @author bratseth
*/
-public class SearchHandlerTestCase {
+public class SearchHandlerTest {
private static final String testDir = "src/test/java/com/yahoo/search/handler/test/config";
private static final String myHostnameHeader = "my-hostname-header";
@@ -59,6 +58,7 @@ public class SearchHandlerTestCase {
private RequestHandlerTestDriver driver = null;
private HandlersConfigurerTestWrapper configurer = null;
+ private MockMetric metric;
private SearchHandler searchHandler;
@Before
@@ -72,6 +72,7 @@ public class SearchHandlerTestCase {
configurer = new HandlersConfigurerTestWrapper(new Container(), configId);
searchHandler = (SearchHandler)configurer.getRequestHandlerRegistry().getComponent(SearchHandler.class.getName());
+ metric = (MockMetric) searchHandler.metric();
driver = new RequestHandlerTestDriver(searchHandler);
}
@@ -289,6 +290,7 @@ public class SearchHandlerTestCase {
assertEquals(expected, response.readAll());
assertEquals(200, response.getStatus());
assertEquals(selfHostname, response.getResponse().headers().get(myHostnameHeader).get(0));
+ assertTrue(metric.metrics().containsKey(SearchHandler.RENDER_LATENCY_METRIC));
}
@Test
@@ -310,7 +312,7 @@ public class SearchHandlerTestCase {
}
private void assertHandlerResponse(int status, String responseData, String handlerName) throws Exception {
- RequestHandler forwardingHandler = configurer.getRequestHandlerRegistry().getComponent("com.yahoo.search.handler.test.SearchHandlerTestCase$" + handlerName + "Handler");
+ RequestHandler forwardingHandler = configurer.getRequestHandlerRegistry().getComponent("com.yahoo.search.handler.SearchHandlerTest$" + handlerName + "Handler");
try (RequestHandlerTestDriver forwardingDriver = new RequestHandlerTestDriver(forwardingHandler)) {
RequestHandlerTestDriver.MockResponseHandler response = forwardingDriver.sendRequest("http://localhost/" + handlerName + "?query=test");
response.awaitResponse();
diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg b/container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg
index 9a16c6ed1e7..f7eba221ef1 100644
--- a/container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg
+++ b/container-search/src/test/java/com/yahoo/search/handler/test/config/chains.cfg
@@ -1,20 +1,20 @@
chains[4]
chains[0].id default
chains[0].components[1]
-chains[0].components[0] com.yahoo.search.handler.test.SearchHandlerTestCase$TestSearcher
+chains[0].components[0] com.yahoo.search.handler.SearchHandlerTest$TestSearcher
chains[1].id classLoadingError
chains[1].components[1]
-chains[1].components[0] com.yahoo.search.handler.test.SearchHandlerTestCase$ClassLoadingErrorSearcher
+chains[1].components[0] com.yahoo.search.handler.SearchHandlerTest$ClassLoadingErrorSearcher
chains[2].id exceptionInPlugin
chains[2].components[1]
-chains[2].components[0] com.yahoo.search.handler.test.SearchHandlerTestCase$ExceptionInPluginSearcher
+chains[2].components[0] com.yahoo.search.handler.SearchHandlerTest$ExceptionInPluginSearcher
chains[3].id echoingQuery
chains[3].components[2]
chains[3].components[0] com.yahoo.search.yql.MinimalQueryInserter
-chains[3].components[1] com.yahoo.search.handler.test.SearchHandlerTestCase$EchoingQuerySearcher
+chains[3].components[1] com.yahoo.search.handler.SearchHandlerTest$EchoingQuerySearcher
components[5]
-components[0].id com.yahoo.search.handler.test.SearchHandlerTestCase$TestSearcher
-components[1].id com.yahoo.search.handler.test.SearchHandlerTestCase$ClassLoadingErrorSearcher
-components[2].id com.yahoo.search.handler.test.SearchHandlerTestCase$ExceptionInPluginSearcher
-components[3].id com.yahoo.search.handler.test.SearchHandlerTestCase$EchoingQuerySearcher
+components[0].id com.yahoo.search.handler.SearchHandlerTest$TestSearcher
+components[1].id com.yahoo.search.handler.SearchHandlerTest$ClassLoadingErrorSearcher
+components[2].id com.yahoo.search.handler.SearchHandlerTest$ExceptionInPluginSearcher
+components[3].id com.yahoo.search.handler.SearchHandlerTest$EchoingQuerySearcher
components[4].id com.yahoo.search.yql.MinimalQueryInserter
diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/config/handlers.cfg b/container-search/src/test/java/com/yahoo/search/handler/test/config/handlers.cfg
index 915da8dc037..12f218581d5 100644
--- a/container-search/src/test/java/com/yahoo/search/handler/test/config/handlers.cfg
+++ b/container-search/src/test/java/com/yahoo/search/handler/test/config/handlers.cfg
@@ -1,9 +1,9 @@
handler[8]
handler[0].id com.yahoo.search.handler.SearchHandler
-handler[1].id com.yahoo.search.handler.test.SearchHandlerTestCase$NullReturningHandler
-handler[2].id com.yahoo.search.handler.test.SearchHandlerTestCase$NullReturningAsyncHandler
-handler[3].id com.yahoo.search.handler.test.SearchHandlerTestCase$ThrowingHandler
-handler[4].id com.yahoo.search.handler.test.SearchHandlerTestCase$ThrowingAsyncHandler
-handler[5].id com.yahoo.search.handler.test.SearchHandlerTestCase$ForwardingHandler
-handler[6].id com.yahoo.search.handler.test.SearchHandlerTestCase$ForwardingAsyncHandler
+handler[1].id com.yahoo.search.handler.SearchHandlerTest$NullReturningHandler
+handler[2].id com.yahoo.search.handler.SearchHandlerTest$NullReturningAsyncHandler
+handler[3].id com.yahoo.search.handler.SearchHandlerTest$ThrowingHandler
+handler[4].id com.yahoo.search.handler.SearchHandlerTest$ThrowingAsyncHandler
+handler[5].id com.yahoo.search.handler.SearchHandlerTest$ForwardingHandler
+handler[6].id com.yahoo.search.handler.SearchHandlerTest$ForwardingAsyncHandler
handler[7].id com.yahoo.search.query.profile.compiled.CompiledQueryProfileRegistry
diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/config/handlers2/chains.cfg b/container-search/src/test/java/com/yahoo/search/handler/test/config/handlers2/chains.cfg
index 2437efdec4f..83db7ef1cc9 100644
--- a/container-search/src/test/java/com/yahoo/search/handler/test/config/handlers2/chains.cfg
+++ b/container-search/src/test/java/com/yahoo/search/handler/test/config/handlers2/chains.cfg
@@ -1,10 +1,10 @@
chains[2]
chains[0].id default
chains[0].components[1]
-chains[0].components[0] com.yahoo.search.handler.test.SearchHandlerTestCase$TestSearcher
+chains[0].components[0] com.yahoo.search.handler.SearchHandlerTest$TestSearcher
chains[1].id hello
chains[1].components[1]
-chains[1].components[0] com.yahoo.search.handler.test.SearchHandlerTestCase$HelloWorldSearcher
+chains[1].components[0] com.yahoo.search.handler.SearchHandlerTest$HelloWorldSearcher
components[2]
-components[0].id com.yahoo.search.handler.test.SearchHandlerTestCase$TestSearcher
-components[1].id com.yahoo.search.handler.test.SearchHandlerTestCase$HelloWorldSearcher
+components[0].id com.yahoo.search.handler.SearchHandlerTest$TestSearcher
+components[1].id com.yahoo.search.handler.SearchHandlerTest$HelloWorldSearcher
diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/config/handlersInvalid/handlers.cfg b/container-search/src/test/java/com/yahoo/search/handler/test/config/handlersInvalid/handlers.cfg
index 691b37b4955..9dd1aff9d06 100644
--- a/container-search/src/test/java/com/yahoo/search/handler/test/config/handlersInvalid/handlers.cfg
+++ b/container-search/src/test/java/com/yahoo/search/handler/test/config/handlersInvalid/handlers.cfg
@@ -1,3 +1,3 @@
handler[2]
handler[0].id com.yahoo.search.handler.SearchHandler
-handler[1].id com.yahoo.search.handler.test.SearchHandlerTestCase$ErrorOnInitializationHandler
+handler[1].id com.yahoo.search.handler.SearchHandlerTest$ErrorOnInitializationHandler