Hey folks,
I needed a way to keep track of individual ZK instances' memory usage
without using JMX, so I went and added a new four letter word: memo
Example usage:
# echo memo | nc 127.0.0.1 44011
Maximum memory: 514850816
Free memory: 479290568
Total memory: 514850816
This exposes the same data that ZOOKEEPER-716 logs, basically the
runtime's maximum/free/total memory.
Attached patch is against branch-3.4.13 as that's the version we're
currently using.
Any feedback is highly appreciated.
Should I go ahead and create a PR/Jira issue?
Thanks,
- Bram
diff --git a/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml b/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml
index d88ddbdb..858448d4 100644
--- a/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml
+++ b/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml
@@ -1180,6 +1180,14 @@ server.3=zoo3:2888:3888</programlisting>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>memo</term>
+
+ <listitem>
+ <para>Gets server memory usage information.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>gtmk</term>
diff --git a/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java b/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
index 24cc7b46..b922c407 100644
--- a/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
+++ b/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
@@ -850,6 +850,29 @@ public void commandRun() {
}
}
+ /**
+ * The memo command prints basic memory usage information (in bytes):
+ * - The JVM's max memory (Xmx)
+ * - The current free memory
+ * - The totally allocated memory
+ */
+ private class MemoCommand extends CommandThread {
+ public MemoCommand(PrintWriter pw) {
+ super(pw);
+ }
+
+ @Override
+ public void commandRun() {
+ final Runtime runtime = Runtime.getRuntime();
+ pw.print("Maximum memory: ");
+ pw.println(runtime.maxMemory());
+ pw.print("Free memory: ");
+ pw.println(runtime.freeMemory());
+ pw.print("Total memory: ");
+ pw.println(runtime.totalMemory());
+ }
+ }
+
private class NopCommand extends CommandThread {
private String msg;
@@ -969,6 +992,10 @@ private boolean checkFourLetterWord(final SelectionKey k, final int len)
IsroCommand isro = new IsroCommand(pwriter);
isro.start();
return true;
+ } else if (len == memoCmd) {
+ MemoCommand memo = new MemoCommand(pwriter);
+ memo.start();
+ return true;
}
return false;
}
diff --git a/src/java/main/org/apache/zookeeper/server/NettyServerCnxn.java b/src/java/main/org/apache/zookeeper/server/NettyServerCnxn.java
index 271fc19e..428e9a85 100644
--- a/src/java/main/org/apache/zookeeper/server/NettyServerCnxn.java
+++ b/src/java/main/org/apache/zookeeper/server/NettyServerCnxn.java
@@ -630,6 +630,29 @@ public void commandRun() {
}
}
+ /**
+ * The memo command prints basic memory usage information (in bytes):
+ * - The JVM's max memory (Xmx)
+ * - The current free memory
+ * - The totally allocated memory
+ */
+ private class MemoCommand extends CommandThread {
+ public MemoCommand(PrintWriter pw) {
+ super(pw);
+ }
+
+ @Override
+ public void commandRun() {
+ final Runtime runtime = Runtime.getRuntime();
+ pw.print("Maximum memory: ");
+ pw.println(runtime.maxMemory());
+ pw.print("Free memory: ");
+ pw.println(runtime.freeMemory());
+ pw.print("Total memory: ");
+ pw.println(runtime.totalMemory());
+ }
+ }
+
private class NopCommand extends CommandThread {
private String msg;
@@ -728,6 +751,10 @@ private boolean checkFourLetterWord(final Channel channel,
IsroCommand isro = new IsroCommand(pwriter);
isro.start();
return true;
+ } else if (len == memoCmd) {
+ MemoCommand memo = new MemoCommand(pwriter);
+ memo.start();
+ return true;
}
return false;
}
diff --git a/src/java/main/org/apache/zookeeper/server/ServerCnxn.java b/src/java/main/org/apache/zookeeper/server/ServerCnxn.java
index dfa1d74e..95968ba2 100644
--- a/src/java/main/org/apache/zookeeper/server/ServerCnxn.java
+++ b/src/java/main/org/apache/zookeeper/server/ServerCnxn.java
@@ -240,6 +240,13 @@ public String toString() {
protected final static int isroCmd = ByteBuffer.wrap("isro".getBytes())
.getInt();
+ /*
+ * See <a href="{@docRoot}/../../../docs/zookeeperAdmin.html#sc_zkCommands">
+ * Zk Admin</a>. this link is for all the commands.
+ */
+ protected final static int memoCmd = ByteBuffer.wrap("memo".getBytes())
+ .getInt();
+
final static Map<Integer, String> cmd2String = new HashMap<Integer, String>();
private static final String ZOOKEEPER_4LW_COMMANDS_WHITELIST = "zookeeper.4lw.commands.whitelist";
@@ -344,6 +351,7 @@ public synchronized static boolean isEnabled(String command) {
cmd2String.put(wchsCmd, "wchs");
cmd2String.put(mntrCmd, "mntr");
cmd2String.put(isroCmd, "isro");
+ cmd2String.put(memoCmd, "memo");
}
protected void packetReceived() {
diff --git a/src/java/test/org/apache/zookeeper/test/FourLetterWordsTest.java b/src/java/test/org/apache/zookeeper/test/FourLetterWordsTest.java
index bc8d0713..4f054082 100644
--- a/src/java/test/org/apache/zookeeper/test/FourLetterWordsTest.java
+++ b/src/java/test/org/apache/zookeeper/test/FourLetterWordsTest.java
@@ -106,6 +106,10 @@ public void testFourLetterWords() throws Exception {
verify("mntr", "fsync_threshold_exceed_count");
verify("stat", "Connections");
verify("srvr", "Connections");
+
+ verify("memo", "Free memory");
+ verify("memo", "Total memory");
+ verify("memo", "Maximum memory");
}
private String sendRequest(String cmd) throws IOException {