From 96468ebd543df13aade236b3459a5589abe58d0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C5=A1a=20=C5=BDivkov?= Date: Fri, 6 Jun 2014 15:02:09 +0200 Subject: [PATCH] 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 --- Documentation/cmd-show-caches.txt | 3 + .../gerrit/sshd/commands/ShowCaches.java | 70 +++++++++++++++++-- 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/Documentation/cmd-show-caches.txt b/Documentation/cmd-show-caches.txt index facd1331cb..b5c04f70f9 100644 --- a/Documentation/cmd-show-caches.txt +++ b/Documentation/cmd-show-caches.txt @@ -22,6 +22,9 @@ Display statistics about the size and hit ratio of in-memory caches. operating system, and other details about the environment that Gerrit Code Review is running in. +--show-threads:: + Show detailed counts for Gerrit specific threads. + --width:: -w:: Width of the output table. diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowCaches.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowCaches.java index 00ccae271b..2c9c56cc96 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowCaches.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ShowCaches.java @@ -17,6 +17,8 @@ package com.google.gerrit.sshd.commands; import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE; 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.data.GlobalCapability; import com.google.gerrit.extensions.annotations.RequiresCapability; @@ -47,11 +49,15 @@ import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.lang.management.RuntimeMXBean; +import java.lang.management.ThreadInfo; +import java.lang.management.ThreadMXBean; import java.net.InetAddress; import java.net.UnknownHostException; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Collection; import java.util.Date; +import java.util.List; import java.util.Map; /** Show the current cache states. */ @@ -78,6 +84,9 @@ final class ShowCaches extends SshCommand { @Option(name = "--show-jvm", usage = "show details about the JVM") private boolean showJVM; + @Option(name = "--show-threads", usage = "show detailed thread counts") + private boolean showThreads; + @Inject private WorkQueue workQueue; @@ -163,6 +172,7 @@ final class ShowCaches extends SshCommand { sshSummary(); taskSummary(); memSummary(); + threadSummary(); if (showJVM) { jvmSummary(); @@ -245,13 +255,65 @@ final class ShowCaches extends SshCommand { bytes(mFree), bytes(jgitBytes)); stdout.format(" %s max\n", bytes(mMax)); - stdout.format(" %8d open files, %8d cpus available, %8d threads\n", - jgitOpen, - r.availableProcessors(), - ManagementFactory.getThreadMXBean().getThreadCount()); + stdout.format(" %8d open files\n", jgitOpen); stdout.print('\n'); } + private void threadSummary() { + List 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 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 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() { Collection> pending = workQueue.getTasks(); int tasksTotal = pending.size();