diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2020-03-16 11:13:18 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-16 11:13:18 +0100 |
commit | e4253f68b134d16e48a1f6e3e6dbf9d909cf919a (patch) | |
tree | 556f2e6a56f0c3e564c994d11e708a0cbae12c8f /container-core/src/main | |
parent | acd8d9298c837a9005f0f54e8da062260d7339cc (diff) | |
parent | 0060db436df1b9e6084bcf97939ead48109af078 (diff) |
Merge pull request #12534 from vespa-engine/bjorncs/jdisc-metric-unhandled-exception
Bjorncs/jdisc metric unhandled exception
Diffstat (limited to 'container-core/src/main')
3 files changed, 19 insertions, 3 deletions
diff --git a/container-core/src/main/java/com/yahoo/container/handler/ThreadPoolProvider.java b/container-core/src/main/java/com/yahoo/container/handler/ThreadPoolProvider.java index 4cc3b48fd1a..b427a58c9b7 100644 --- a/container-core/src/main/java/com/yahoo/container/handler/ThreadPoolProvider.java +++ b/container-core/src/main/java/com/yahoo/container/handler/ThreadPoolProvider.java @@ -9,6 +9,7 @@ import com.yahoo.container.di.componentgraph.Provider; import com.yahoo.container.protect.ProcessTerminator; import com.yahoo.jdisc.Metric; +import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executor; import java.util.concurrent.ExecutorService; @@ -43,7 +44,8 @@ public class ThreadPoolProvider extends AbstractComponent implements Provider<Ex threadpoolConfig.maxthreads(), 0L, TimeUnit.SECONDS, new SynchronousQueue<>(false), - ThreadFactoryFactory.getThreadFactory("threadpool")); + ThreadFactoryFactory.getThreadFactory("threadpool"), + metric); // Prestart needed, if not all threads will be created by the fist N tasks and hence they might also // get the dreaded thread locals initialized even if they will never run. // That counters what we we want to achieve with the Q that will prefer thread locality. @@ -161,17 +163,22 @@ public class ThreadPoolProvider extends AbstractComponent implements Provider<Ex /** A thread pool executor which maintains the last time a worker completed */ private final static class WorkerCompletionTimingThreadPoolExecutor extends ThreadPoolExecutor { + private static final String UNHANDLED_EXCEPTIONS_METRIC = "jdisc.thread_pool.unhandled_exceptions"; + volatile long lastThreadAssignmentTimeMillis = System.currentTimeMillis(); private final AtomicLong startedCount = new AtomicLong(0); private final AtomicLong completedCount = new AtomicLong(0); + private final Metric metric; public WorkerCompletionTimingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, - ThreadFactory threadFactory) { + ThreadFactory threadFactory, + Metric metric) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory); + this.metric = metric; } @Override @@ -185,6 +192,9 @@ public class ThreadPoolProvider extends AbstractComponent implements Provider<Ex protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); completedCount.incrementAndGet(); + if (t != null) { + metric.add(UNHANDLED_EXCEPTIONS_METRIC, 1L, metric.createContext(Map.of("exception", t.getClass().getSimpleName()))); + } } @Override diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedHttpRequestHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedHttpRequestHandler.java index a9ea737c96c..c58d49bf8c8 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedHttpRequestHandler.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedHttpRequestHandler.java @@ -13,6 +13,7 @@ import com.yahoo.log.LogLevel; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.Map; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; @@ -31,6 +32,7 @@ public abstract class ThreadedHttpRequestHandler extends ThreadedRequestHandler public static final String CONTENT_TYPE = "Content-Type"; private static final String RENDERING_ERRORS = "rendering_errors"; + private static final String UNHANDLED_EXCEPTIONS_METRIC = "jdisc.http.handler.unhandled_exceptions"; /** Logger for subclasses */ protected final Logger log; @@ -79,6 +81,7 @@ public abstract class ThreadedHttpRequestHandler extends ThreadedRequestHandler channel.setHttpResponse(httpResponse); // may or may not have already been done render(httpRequest, httpResponse, channel, jdiscRequest.creationTime(TimeUnit.MILLISECONDS)); } catch (Exception e) { + metric.add(UNHANDLED_EXCEPTIONS_METRIC, 1L, contextFor(request, Map.of("exception", e.getClass().getSimpleName()))); metric.add(RENDERING_ERRORS, 1, null); log.log(LogLevel.ERROR, "Uncaught exception handling request", e); if (channel != null) { diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedRequestHandler.java b/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedRequestHandler.java index 6c8cee8433c..99732af9d31 100644 --- a/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedRequestHandler.java +++ b/container-core/src/main/java/com/yahoo/container/jdisc/ThreadedRequestHandler.java @@ -79,7 +79,7 @@ public abstract class ThreadedRequestHandler extends AbstractRequestHandler { this.allowAsyncResponse = allowAsyncResponse; } - private Metric.Context contextFor(Request request) { + Metric.Context contextFor(Request request, Map<String, String> extraDimensions) { BindingMatch match = request.getBindingMatch(); if (match == null) return null; UriPattern matched = match.matched(); @@ -97,9 +97,12 @@ public abstract class ThreadedRequestHandler extends AbstractRequestHandler { dimensions.put("port", Integer.toString(uri.getPort())); String handlerClassName = getClass().getName(); dimensions.put("handler-name", handlerClassName); + dimensions.putAll(extraDimensions); return this.metric.createContext(dimensions); } + private Metric.Context contextFor(Request request) { return contextFor(request, Map.of()); } + /** * Handles a request by assigning a worker thread to it. * |