SSH show-queue: option to group output by queue and print queue info
When the new option --by-queue is used the output of the show-queue command is grouped by the work queue. Queue name is printed on top of the tasks list and the number of worker threads assigned to that thread pool is printed in the summary line. This option should help Gerrit admins to identify which thread pools need to be adjusted. For comparison, here is an example output without the new --by-queue option: Task State StartTime Command ------------------------------------------------------------------------------ 9d51b721 16:29:14.750 git-upload-pack '/gerrit' (admin) 18fr4561 16:29:14.750 git-upload-pack '/gerrit' (admin) ad52b823 16:29:14.750 git-upload-pack '/gerrit' (admin) bd51bbcc 16:29:14.750 git-upload-pack '/gerrit' (admin) 11223344 16:29:14.750 git-upload-pack '/gerrit' (admin) 3d120b5c 17:28:20.169 16:28:20.169 Log File Compressor ------------------------------------------------------------------------------ 6 tasks With the --by-queue option the output looks like: $ ssh -p29418 admin@localhost gerrit show-queue -w --by-queue Task State StartTime Command ------------------------------------------------------------------------------ Queue: SSH-Interactive-Worker 9d51b721 16:29:14.750 git-upload-pack '/gerrit' (admin) 18fr4561 16:29:14.750 git-upload-pack '/gerrit' (admin) ad52b823 16:29:14.750 git-upload-pack '/gerrit' (admin) bd51bbcc 16:29:14.750 git-upload-pack '/gerrit' (admin) 11223344 16:29:14.750 git-upload-pack '/gerrit' (admin) ------------------------------------------------------------------------------ 5 tasks, 14 worker threads Queue: WorkQueue 3d120b5c 17:28:20.169 16:28:20.169 Log File Compressor ------------------------------------------------------------------------------ 1 tasks, 1 worker threads Change-Id: If82bdb50702f2001f887fe5004b0d80b61131a90
This commit is contained in:
parent
89634f70f3
commit
eaf64568a7
@ -39,6 +39,10 @@ Intended for interactive use only.
|
||||
Do not format the output to the terminal width (default of
|
||||
80 columns).
|
||||
|
||||
--by-queue::
|
||||
-q::
|
||||
Group tasks by queue and print queue info.
|
||||
|
||||
== DISPLAY
|
||||
|
||||
Task::
|
||||
|
@ -113,6 +113,7 @@ public class ListTasks implements RestReadView<ConfigResource> {
|
||||
public String command;
|
||||
public String remoteName;
|
||||
public String projectName;
|
||||
public String queueName;
|
||||
|
||||
public TaskInfo(Task<?> task) {
|
||||
this.id = IdGenerator.format(task.getTaskId());
|
||||
@ -120,6 +121,7 @@ public class ListTasks implements RestReadView<ConfigResource> {
|
||||
this.startTime = new Timestamp(task.getStartTime().getTime());
|
||||
this.delay = task.getDelay(TimeUnit.MILLISECONDS);
|
||||
this.command = task.toString();
|
||||
this.queueName = task.getQueueName();
|
||||
|
||||
if (task instanceof ProjectTask) {
|
||||
ProjectTask<?> projectTask = ((ProjectTask<?>) task);
|
||||
|
@ -152,6 +152,15 @@ public class WorkQueue {
|
||||
return result;
|
||||
}
|
||||
|
||||
public Executor getExecutor(String queueName) {
|
||||
for (Executor e : queues) {
|
||||
if (e.queueName.equals(queueName)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void stop() {
|
||||
for (final Executor p : queues) {
|
||||
p.shutdown();
|
||||
@ -170,8 +179,9 @@ public class WorkQueue {
|
||||
/** An isolated queue. */
|
||||
public class Executor extends ScheduledThreadPoolExecutor {
|
||||
private final ConcurrentHashMap<Integer, Task<?>> all;
|
||||
private final String queueName;
|
||||
|
||||
Executor(final int corePoolSize, final String prefix) {
|
||||
Executor(int corePoolSize, final String prefix) {
|
||||
super(corePoolSize, new ThreadFactory() {
|
||||
private final ThreadFactory parent = Executors.defaultThreadFactory();
|
||||
private final AtomicInteger tid = new AtomicInteger(1);
|
||||
@ -190,6 +200,7 @@ public class WorkQueue {
|
||||
0.75f, // load factor
|
||||
corePoolSize + 4 // concurrency level
|
||||
);
|
||||
queueName = prefix;
|
||||
}
|
||||
|
||||
public void unregisterWorkQueue() {
|
||||
@ -325,6 +336,10 @@ public class WorkQueue {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public String getQueueName() {
|
||||
return executor.queueName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
if (task.cancel(mayInterruptIfRunning)) {
|
||||
|
@ -17,12 +17,15 @@ package com.google.gerrit.sshd.commands;
|
||||
import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.collect.LinkedListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
import com.google.gerrit.common.TimeUtil;
|
||||
import com.google.gerrit.extensions.restapi.AuthException;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.config.ConfigResource;
|
||||
import com.google.gerrit.server.config.ListTasks;
|
||||
import com.google.gerrit.server.config.ListTasks.TaskInfo;
|
||||
import com.google.gerrit.server.git.WorkQueue;
|
||||
import com.google.gerrit.server.git.WorkQueue.Task;
|
||||
import com.google.gerrit.sshd.AdminHighPriorityCommand;
|
||||
import com.google.gerrit.sshd.CommandMetaData;
|
||||
@ -39,18 +42,27 @@ import java.util.List;
|
||||
|
||||
/** Display the current work queue. */
|
||||
@AdminHighPriorityCommand
|
||||
@CommandMetaData(name = "show-queue", description = "Display the background work queues",
|
||||
runsAt = MASTER_OR_SLAVE)
|
||||
@CommandMetaData(name = "show-queue",
|
||||
description = "Display the background work queues",
|
||||
runsAt = MASTER_OR_SLAVE)
|
||||
final class ShowQueue extends SshCommand {
|
||||
@Option(name = "--wide", aliases = {"-w"}, usage = "display without line width truncation")
|
||||
@Option(name = "--wide", aliases = {"-w"},
|
||||
usage = "display without line width truncation")
|
||||
private boolean wide;
|
||||
|
||||
@Option(name = "--by-queue", aliases = {"-q"},
|
||||
usage = "group tasks by queue and print queue info")
|
||||
private boolean groupByQueue;
|
||||
|
||||
@Inject
|
||||
private ListTasks listTasks;
|
||||
|
||||
@Inject
|
||||
private IdentifiedUser currentUser;
|
||||
|
||||
@Inject
|
||||
private WorkQueue workQueue;
|
||||
|
||||
private int columns = 80;
|
||||
private int maxCommandWidth;
|
||||
|
||||
@ -75,50 +87,78 @@ final class ShowQueue extends SshCommand {
|
||||
stdout.print("----------------------------------------------"
|
||||
+ "--------------------------------\n");
|
||||
|
||||
List<TaskInfo> tasks;
|
||||
try {
|
||||
List<TaskInfo> tasks = listTasks.apply(new ConfigResource());
|
||||
long now = TimeUtil.nowMs();
|
||||
boolean viewAll = currentUser.getCapabilities().canViewQueue();
|
||||
for (TaskInfo task : tasks) {
|
||||
String start;
|
||||
switch (task.state) {
|
||||
case DONE:
|
||||
case CANCELLED:
|
||||
case RUNNING:
|
||||
case READY:
|
||||
start = format(task.state);
|
||||
break;
|
||||
case OTHER:
|
||||
case SLEEPING:
|
||||
default:
|
||||
start = time(now, task.delay);
|
||||
break;
|
||||
}
|
||||
|
||||
// Shows information about tasks depending on the user rights
|
||||
if (viewAll || task.projectName == null) {
|
||||
String command = task.command.length() < maxCommandWidth
|
||||
? task.command
|
||||
: task.command.substring(0, maxCommandWidth);
|
||||
|
||||
stdout.print(String.format("%8s %-12s %-12s %-4s %s\n",
|
||||
task.id, start, startTime(task.startTime), "", command));
|
||||
} else {
|
||||
String remoteName = task.remoteName != null
|
||||
? task.remoteName + "/" + task.projectName
|
||||
: task.projectName;
|
||||
|
||||
stdout.print(String.format("%8s %-12s %-4s %s\n",
|
||||
task.id, start, startTime(task.startTime),
|
||||
MoreObjects.firstNonNull(remoteName, "n/a")));
|
||||
}
|
||||
}
|
||||
stdout.print("----------------------------------------------"
|
||||
+ "--------------------------------\n");
|
||||
stdout.print(" " + tasks.size() + " tasks\n");
|
||||
tasks = listTasks.apply(new ConfigResource());
|
||||
} catch (AuthException e) {
|
||||
throw die(e);
|
||||
}
|
||||
boolean viewAll = currentUser.getCapabilities().canViewQueue();
|
||||
long now = TimeUtil.nowMs();
|
||||
|
||||
if (groupByQueue) {
|
||||
ListMultimap<String, TaskInfo> byQueue = byQueue(tasks);
|
||||
for (String queueName : byQueue.keySet()) {
|
||||
WorkQueue.Executor e = workQueue.getExecutor(queueName);
|
||||
stdout.print(String.format("Queue: %s\n", queueName));
|
||||
print(byQueue.get(queueName), now, viewAll, e.getCorePoolSize());
|
||||
}
|
||||
} else {
|
||||
print(tasks, now, viewAll, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private ListMultimap<String, TaskInfo> byQueue(List<TaskInfo> tasks) {
|
||||
ListMultimap<String, TaskInfo> byQueue = LinkedListMultimap.create();
|
||||
for (TaskInfo task : tasks) {
|
||||
byQueue.put(task.queueName, task);
|
||||
}
|
||||
return byQueue;
|
||||
}
|
||||
|
||||
private void print(List<TaskInfo> tasks, long now, boolean viewAll,
|
||||
int threadPoolSize) {
|
||||
for (TaskInfo task : tasks) {
|
||||
String start;
|
||||
switch (task.state) {
|
||||
case DONE:
|
||||
case CANCELLED:
|
||||
case RUNNING:
|
||||
case READY:
|
||||
start = format(task.state);
|
||||
break;
|
||||
case OTHER:
|
||||
case SLEEPING:
|
||||
default:
|
||||
start = time(now, task.delay);
|
||||
break;
|
||||
}
|
||||
|
||||
// Shows information about tasks depending on the user rights
|
||||
if (viewAll || task.projectName == null) {
|
||||
String command = task.command.length() < maxCommandWidth
|
||||
? task.command
|
||||
: task.command.substring(0, maxCommandWidth);
|
||||
|
||||
stdout.print(String.format("%8s %-12s %-12s %-4s %s\n",
|
||||
task.id, start, startTime(task.startTime), "", command));
|
||||
} else {
|
||||
String remoteName = task.remoteName != null
|
||||
? task.remoteName + "/" + task.projectName
|
||||
: task.projectName;
|
||||
|
||||
stdout.print(String.format("%8s %-12s %-4s %s\n",
|
||||
task.id, start, startTime(task.startTime),
|
||||
MoreObjects.firstNonNull(remoteName, "n/a")));
|
||||
}
|
||||
}
|
||||
stdout.print("----------------------------------------------"
|
||||
+ "--------------------------------\n");
|
||||
stdout.print(" " + tasks.size() + " tasks");
|
||||
if (threadPoolSize > 0) {
|
||||
stdout.print(", " + threadPoolSize + " worker threads");
|
||||
}
|
||||
stdout.print("\n\n");
|
||||
}
|
||||
|
||||
private static String time(long now, long delay) {
|
||||
|
Loading…
Reference in New Issue
Block a user