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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user