- Enable JMX in your Tomcat, e.g. by adding following parameters to its java command line.
-Dsun.management.jmxremote -Dcom.sun.management.jmxremote.port=3993
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
As you see this settings turns off both SSL and authentication, to make this simplem, although not secure.
Jmxterm does not support SSL yet, password-based authentication in command open is supported (use help open in jmxterm shell for more info). - Download jmxterm from http://sourceforge.net/projects/cyclops-group/files/jmxterm/
- Start in interactive mode to test commands:
java -jar jmxterm-${version}-uber.jar
(for ${version} substitute current version of jxmterm, e.g. "1.0-alpha-4") - Run commands to get desired data
- open localhost:3993
- Restricts output of following commands to given domain - select domain: domain Catalina.
- Now you can list beans:
beans - now the domain is set and we get values of some attributes:
- get -b Catalina:port=80,type=Connector acceptCountget -b Catalina:port=80,type=Connector acceptCount
#mbean = Catalina:port=80,type=Connector:
acceptCount = 100;
- get -b name=http-80,type=ThreadPool maxThreadsget -b name=http-80,type=ThreadPool maxThreads
#mbean = Catalina:name=http-80,type=ThreadPool:
maxThreads = 40;
- get -b name=http-80,type=ThreadPool currentThreadCountget -b name=http-80,type=ThreadPool currentThreadCount
#mbean = Catalina:name=http-80,type=ThreadPool:
currentThreadCount = 15;
- get -b name=http-80,type=ThreadPool currentThreadsBusyget -b name=http-80,type=ThreadPool currentThreadsBusy
#mbean = Catalina:name=http-80,type=ThreadPool:
currentThreadsBusy = 2; - get -b Catalina:host=localhost,path=${webapp_context},type=Manager activeSessionsget -b Catalina:host=localhost,path=${webapp_context},type=Manager activeSessions
#mbean = Catalina:host=localhost,path=${webapp_context},type=Manager:
activeSessions = 3; - Put commands in file and run this scripts in non-interactive way
java -jar jmxterm-${version}-uber.jar -nor
java -jar jmxterm-${version}-uber.jar -n -i jmx_script
content of the file jmx_script:
open localhost:3993get -d Catalina -b Catalina:port=80,type=Connector acceptCountget -d Catalina -b name=http-80,type=ThreadPool maxThreadsget -d Catalina -b name=http-80,type=ThreadPool currentThreadCountget -d Catalina -b name=http-80,type=ThreadPool currentThreadsBusyquit
Output:
Welcome to JMX terminal. Type "help" for available commands.
#Connection to localhost:3993 is opened
#mbean = Catalina:port=80,type=Connector:
acceptCount = 100;
#mbean = Catalina:name=http-80,type=ThreadPool:
maxThreads = 40;
#mbean = Catalina:name=http-80,type=ThreadPool:
currentThreadCount = 18;
#mbean = Catalina:name=http-80,type=ThreadPool:
currentThreadsBusy = 5;
#bye
get -d Catalina -b ${bean_name} ${attribute_name}
Wrapping in Python
The problem with jmxterm si that its startup time is really long - even several seconds. Also connecting to process can take second or two. The reponsivness is good so if you need it for periodic monitoring, you would like to start it and connect and then fire requests when you need the data. After trying some approaches I settled on Python pexpect for this (script reduced to minimum):
import time import pexpect connection = "localhost:3993" connection_timeout = 2 jmxterm = pexpect.spawn("java -jar jmxterm-1.0-alpha-4-uber.jar") jmxterm.expect_exact("$>") # got prompt, we can continue jmxterm.sendline("open " + connection) jmxterm.expect_exact("#Connection to "+connection+" is opened", connection_timeout) jmxterm.sendline("get -d Catalina -b name=http-80,type=ThreadPool currentThreadCount") response_lines = [] response_lines.append(jmxterm.readline()) response_lines.append(jmxterm.readline()) response_lines.append(jmxterm.readline()) response_lines.append(jmxterm.readline()) result = response_lines[3].replace(";"," ").strip().split(" ") del result[1] name,value = result print "["+time.ctime()+"]", name, "=", value jmxterm.sendline("quit")
Thank you for this, it's very helpful.
ReplyDeleteI was trying to do this with subprocess ... pexpect was what i needed !!
Hello,
ReplyDeletevery interesting and powerfull. Is it possible to daemonize in some way this python handler and parse queries to it?
I don't see why it should not be possible. Look at the Twisted (twistedmatrix.com) framework for example, they have even a document about writing servers using Twisted API.
ReplyDelete