Add detailed thread counts to the show-caches command

If the new --show-threads option of the show-caches command is set,
the command prints out detailed counts for Gerrit specific threads.

Change-Id: I05fd70b3e8731d75fe3281da4e59a8117784092e
This commit is contained in:
Saša Živkov 2014-06-06 15:02:09 +02:00
parent 6c9da6d836
commit 96468ebd54
2 changed files with 69 additions and 4 deletions

View File

@ -22,6 +22,9 @@ Display statistics about the size and hit ratio of in-memory caches.
operating system, and other details about the environment operating system, and other details about the environment
that Gerrit Code Review is running in. that Gerrit Code Review is running in.
--show-threads::
Show detailed counts for Gerrit specific threads.
--width:: --width::
-w:: -w::
Width of the output table. Width of the output table.

View File

@ -17,6 +17,8 @@ package com.google.gerrit.sshd.commands;
import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE; import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.google.gerrit.common.Version; import com.google.gerrit.common.Version;
import com.google.gerrit.common.data.GlobalCapability; import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.extensions.annotations.RequiresCapability; import com.google.gerrit.extensions.annotations.RequiresCapability;
@ -47,11 +49,15 @@ import java.io.IOException;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean; import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean; import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map; import java.util.Map;
/** Show the current cache states. */ /** Show the current cache states. */
@ -78,6 +84,9 @@ final class ShowCaches extends SshCommand {
@Option(name = "--show-jvm", usage = "show details about the JVM") @Option(name = "--show-jvm", usage = "show details about the JVM")
private boolean showJVM; private boolean showJVM;
@Option(name = "--show-threads", usage = "show detailed thread counts")
private boolean showThreads;
@Inject @Inject
private WorkQueue workQueue; private WorkQueue workQueue;
@ -163,6 +172,7 @@ final class ShowCaches extends SshCommand {
sshSummary(); sshSummary();
taskSummary(); taskSummary();
memSummary(); memSummary();
threadSummary();
if (showJVM) { if (showJVM) {
jvmSummary(); jvmSummary();
@ -245,13 +255,65 @@ final class ShowCaches extends SshCommand {
bytes(mFree), bytes(mFree),
bytes(jgitBytes)); bytes(jgitBytes));
stdout.format(" %s max\n", bytes(mMax)); stdout.format(" %s max\n", bytes(mMax));
stdout.format(" %8d open files, %8d cpus available, %8d threads\n", stdout.format(" %8d open files\n", jgitOpen);
jgitOpen,
r.availableProcessors(),
ManagementFactory.getThreadMXBean().getThreadCount());
stdout.print('\n'); stdout.print('\n');
} }
private void threadSummary() {
List<String> prefixes = Arrays.asList("HTTP", "IntraLineDiff", "ReceiveCommits",
"SSH git-receive-pack", "SSH git-upload-pack", "SSH-Interactive-Worker",
"SSH-Stream-Worker", "SshCommandStart");
String other = "Other";
Runtime r = Runtime.getRuntime();
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
stdout.format("Threads: %d CPUs available, %d threads\n",
r.availableProcessors(), threadMXBean.getThreadCount());
if (showThreads) {
Table<String, Thread.State, Integer> count = HashBasedTable.create();
for (long id : threadMXBean.getAllThreadIds()) {
ThreadInfo info = threadMXBean.getThreadInfo(id);
if (info == null) {
continue;
}
String name = info.getThreadName();
Thread.State state = info.getThreadState();
String group = other;
for (String p : prefixes) {
if (name.startsWith(p)) {
group = p;
break;
}
}
Integer c = count.get(group, state);
count.put(group, state, c != null ? c + 1 : 1);
}
stdout.print(String.format(" %22s", ""));
for (Thread.State s : Thread.State.values()) {
stdout.print(String.format(" %14s", s.name()));
}
stdout.print('\n');
for (String p : prefixes) {
printThreadCounts(p, count.row(p));
}
printThreadCounts(other, count.row(other));
}
stdout.print('\n');
}
private void printThreadCounts(String title, Map<Thread.State, Integer> counts) {
stdout.print(String.format(" %-22s", title));
for (Thread.State s : Thread.State.values()) {
stdout.print(String.format(" %14d", nullToZero(counts.get(s))));
}
stdout.print('\n');
}
private static int nullToZero(Integer i) {
return i != null ? i.intValue() : 0;
}
private void taskSummary() { private void taskSummary() {
Collection<Task<?>> pending = workQueue.getTasks(); Collection<Task<?>> pending = workQueue.getTasks();
int tasksTotal = pending.size(); int tasksTotal = pending.size();