WorkQueue: Add metrics

Add the following metrics:

* pool_size - Current number of threads in the pool
* max_pool_size - Maximum allowed number of threads in the pool
* active_threads - Number of threads that are actively executing tasks
* scheduled_tasks - Number of scheduled tasks in the queue
* total_scheduled_tasks_count - Total number of tasks that have been scheduled
* total_completed_tasks_count - Total number of tasks that have completed execution

Change-Id: I3f92b840b272a2ee76abef7db89c2a2cda179b72
Signed-off-by: Eryk Szymanski <eryksz@gmail.com>
This commit is contained in:
Eryk Szymanski 2018-05-03 15:04:12 +02:00 committed by David Pursehouse
parent fd5c1672a9
commit eb2f45c84e
2 changed files with 100 additions and 3 deletions

View File

@ -53,6 +53,17 @@ objects needing finalization.
* `query/query_latency`: Successful query latency, accumulated over the life
of the process.
=== Queue
The metrics below are per queue.
* `queue/<queueName>/pool_size`: Current number of threads in the pool
* `queue/<queueName>/max_pool_size`: Maximum allowed number of threads in the pool
* `queue/<queueName>/active_threads`: Number of threads that are actively executing tasks
* `queue/<queueName>/scheduled_tasks`: Number of scheduled tasks in the queue
* `queue/<queueName>/total_scheduled_tasks_count`: Total number of tasks that have been scheduled
* `queue/<queueName>/total_completed_tasks_count`: Total number of tasks that have completed execution
=== SSH sessions
* `sshd/sessions/connected`: Number of currently connected SSH sessions.

View File

@ -14,8 +14,12 @@
package com.google.gerrit.server.git;
import com.google.common.base.CaseFormat;
import com.google.common.base.Supplier;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.lifecycle.LifecycleModule;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.MetricMaker;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.util.IdGenerator;
@ -82,17 +86,19 @@ public class WorkQueue {
}
};
private final MetricMaker metrics;
private final Executor defaultQueue;
private final IdGenerator idGenerator;
private final CopyOnWriteArrayList<Executor> queues;
@Inject
WorkQueue(IdGenerator idGenerator, @GerritServerConfig Config cfg) {
this(idGenerator, cfg.getInt("execution", "defaultThreadPoolSize", 1));
WorkQueue(MetricMaker metrics, IdGenerator idGenerator, @GerritServerConfig Config cfg) {
this(metrics, idGenerator, cfg.getInt("execution", "defaultThreadPoolSize", 1));
}
/** Constructor to allow binding the WorkQueue more explicitly in a vhost setup. */
public WorkQueue(IdGenerator idGenerator, int defaultThreadPoolSize) {
public WorkQueue(MetricMaker metrics, IdGenerator idGenerator, int defaultThreadPoolSize) {
this.metrics = metrics;
this.idGenerator = idGenerator;
this.queues = new CopyOnWriteArrayList<>();
this.defaultQueue = createQueue(defaultThreadPoolSize, "WorkQueue");
@ -199,6 +205,86 @@ public class WorkQueue {
corePoolSize + 4 // concurrency level
);
queueName = prefix;
buildMetrics(queueName, metrics);
}
private void buildMetrics(String queueName, MetricMaker metric) {
metric.newCallbackMetric(
getMetricName(queueName, "max_pool_size"),
Long.class,
new Description("Maximum allowed number of threads in the pool")
.setGauge()
.setUnit("threads"),
new Supplier<Long>() {
@Override
public Long get() {
return (long) getMaximumPoolSize();
}
});
metric.newCallbackMetric(
getMetricName(queueName, "pool_size"),
Long.class,
new Description("Current number of threads in the pool").setGauge().setUnit("threads"),
new Supplier<Long>() {
@Override
public Long get() {
return (long) getPoolSize();
}
});
metric.newCallbackMetric(
getMetricName(queueName, "active_threads"),
Long.class,
new Description("Number number of threads that are actively executing tasks")
.setGauge()
.setUnit("threads"),
new Supplier<Long>() {
@Override
public Long get() {
return (long) getActiveCount();
}
});
metric.newCallbackMetric(
getMetricName(queueName, "scheduled_tasks"),
Integer.class,
new Description("Number of scheduled tasks in the queue").setGauge().setUnit("tasks"),
new Supplier<Integer>() {
@Override
public Integer get() {
return getQueue().size();
}
});
metric.newCallbackMetric(
getMetricName(queueName, "total_scheduled_tasks_count"),
Long.class,
new Description("Total number of tasks that have been scheduled for execution")
.setCumulative()
.setUnit("tasks"),
new Supplier<Long>() {
@Override
public Long get() {
return (long) getTaskCount();
}
});
metric.newCallbackMetric(
getMetricName(queueName, "total_completed_tasks_count"),
Long.class,
new Description("Total number of tasks that have completed execution")
.setCumulative()
.setUnit("tasks"),
new Supplier<Long>() {
@Override
public Long get() {
return (long) getCompletedTaskCount();
}
});
}
private String getMetricName(String queueName, String metricName) {
String name =
CaseFormat.UPPER_CAMEL.to(
CaseFormat.LOWER_UNDERSCORE,
queueName.replaceFirst("SSH", "Ssh").replaceAll("-", ""));
return String.format("queue/%s/%s", name, metricName);
}
public void unregisterWorkQueue() {