I've been learning how to use cassandra lately, and one of the most useful tools when working with it is to be able to query status via all the JMX hooks it exposes. At first I was using jmxterm to query all the available settings, and while this works great, it was tough as a cassandra newb to figure out which beans I needed to query.

What I wanted to do was use JConsole so that I could browse the available beans without having to know a priori what they were. Unfortunately, our production system is all remote (ec2), so this makes it tricky to use JConsole.

At first I tried to use a basic ssh port mapping, but this didn't work due to RMI's need to create its own ports in the JConsole runtime to which the monitored process tries to connect back to - only the single port is tunnelled by ssh. There are a number of documented solutions to doing this, but they all seemed very intrusive and hard to setup correctly (e.g. running a hacked jmx agent within your monitored process).

I then tried using JConsole running remotely but displaying on my local X server, but the performance wasn't that great, and its a pain to have to install all the X runtime on my production system just for running JConsole.

Eventually I smacked my forehead after remembering that ssh can also act as a SOCKs proxy, which works great for any application that supports it. Fortunately, JConsole does (in jdk 1.6 at least).

Here is the bash alias I use to setup the socks connection and connect to my cassandra instance via jconsole. I have multiple remote remote cassandra hosts, so this lets me run JConsole independently for each.

function jc {
ssh -f -D$proxy_port $host 'while true; do sleep 1; done' ssh_pid=`ps ax | grep "[s]sh -f -D$proxy_port" | awk '{print $1}'`
jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=$proxy_port ser
kill $ssh_pid

Once this was in my shell environment, I simply run "jc remote_host", and I get a jconsole connected to my cassandra instance on that host.

Note that you need to set "jconsole_host" in the alias for this to work for you. I'm not sure why, but Its sensitive to the value in here, and only worked for me for the first entry I had in /etc/hosts (not localhost) that maps my local hostname to