Using Groovy for monitoring via JMX
Where I work we had a desire to be able to monitor our application as well as various JVM stats. Currently we use a groovy script to scan the logs every 15 minutes and report on errors if a certain threshold is passed. In our case it is currently 100 errors in that time frame. We also have a heartbeat monitor set up for the servers and we can see the load, session counts, etc. via a customized version of linux’s top.
However, we wanted to be able to see more information. Things like blocked threads, connection pool reaching saturation, spikes in thread creation, etc. Naturally JMX is the appropriate mechanism to achieve all of that, but we wanted a means to automate the process. To script it.
Enter Groovy
I had written a few groovy scripts already, such as the log scanner, so I figured why not use it for JMX stuff as well. While groovy has GroovyMBean object, most of the work was done using the basic JMX api, which wasn’t too bad once you got the hang of it.
The Basics
The first thing to do of course is get a connection to the JMX server. In our case we use an array of URLs to connect to and pull the stats for each in turn.
Here is the connection part:
import javax.management.ObjectName
import javax.management.remote.JMXConnectorFactory as JmxFactory
import javax.management.remote.JMXServiceURL as JmxUrl
import javax.management.MBeanServerConnection
import javax.management.Query
def serverUrls = ['array of connection urls here']
serverUrls.each { serverUrl->
def matcher = serverUrl =~ /.*(web4\d).*/
def box = matcher[0][1]
new File(box + '_stats.txt').withWriter { file->
def server = JmxFactory.connect(new JmxUrl(serverUrl)).mBeanServerConnection
Notice the regex and File object. In our case I’m taking the info and dumping it to a text file, one for each server, and another process reads that file and processes it.
Monitoring Tomcat
The first thing we wanted to do was look at tomcat itself. Namely how many threads are waiting, blocked and running. If there are any blocked threads, then we dump out the thread info for it. So first let us get the Tomcat JMX object:
query = new ObjectName('Catalina:type=Manager,path=/,host=XYZ')
def attr = server.getAttribute(query,"activeSessions")
Naturally you would want to replace “XYZ” for your actual host name. From there, we can start extracting some information:
file.writeLine '#'
file.writeLine '# Tomcat info'
file.writeLine '#'
file.writeLine('activeSessions=' + attr)
file.writeLine('expiredSessions=' + server.getAttribute(query,"expiredSessions") )
file.writeLine('maxActiveSessions=' + server.getAttribute(query,"maxActiveSessions") )
That takes care of some session stuff, now we dive into the threads. First we get a hold of the Threading JMX object and set up some variables.
def threadingObject = new ObjectName('java.lang:type=Threading')
def threadIds = server.getAttribute( threadingObject, 'AllThreadIds' )
def threadCount = 0
def blockedThreads = new ArrayList()
def waitingThreads = 0
def runningThreads = 0
def timedWaiting = 0
Now we loop through all of the thread ids and look specifically for the HTTP threads, which have a name like “http-8080-exec” or “http-8443-exec”:
def sig = ['long']
threadIds.each { id->
def params = new Object[1]
params[0] = id.toLong()
def thread =
server.invoke( threadingObject, 'getThreadInfo',params, sig.toArray( new String[1]) )
if( thread.get('threadName').matches("http-\\d\\d\\d\\d-e.*") ) {
threadCount++
if( thread.get('threadState') == 'TIMED_WAITING' )
timedWaiting++
else if( thread.get('threadState') == 'BLOCKED' )
blockedThreads.add( thread.get('threadName') )
else if( thread.get('threadState') == 'RUNNABLE' )
runningThreads++
else if( thread.get('threadState') =='WAITING' )
waitingThreads++
}
}
Now we write out that info and if there were any blocked threads, we dump out the thread name. From that we can hook into the JVM via JConsole and examine the thread, look for deadlocks, etc. Of course we could probably dump out some of that stuff here too.
file.writeLine "HTTP Threads=" + threadCount
file.writeLine "Waiting Threads=" + waitingThreads
file.writeLine "Timed Waiting Threads=" + timedWaiting
file.writeLine "Running threads=" + runningThreads
file.writeLine "Blocked Thread Count=" + blockedThreads.size()
if( blockedThreads.size() > 0 ) {
file.write( "Blocked Threads=" )
blockedThreads.each{ t->
file.write t+','
}
file.writeLine ''
}
Here we are looking at system level stuff such as the uptime:
//
// System stuff
//
file.writeLine '#'
file.writeLine '# System properties'
file.writeLine '# - uptime is in milliseconds'
file.writeLine '# - ' + (server.getAttribute( new ObjectName('java.lang:type=Runtime'), 'Uptime' )/1000/60/60) + " hours"
file.writeLine 'cpuTime=' + server.getAttribute( new ObjectName('java.lang:type=OperatingSystem'), 'ProcessCpuTime' )
file.writeLine 'uptime=' + server.getAttribute( new ObjectName('java.lang:type=Runtime'), 'Uptime' )
Summary
As you can see, getting info via JMX is fairly easy and straightforward. There is other stuff we look at, such as our connection pool info. We use c3p0 for out pooling and it has a JMX component making that fairly easy as well.
As for processing time, it takes about 7 seconds or so to connect to our 5 servers and write out all of this data, so it is pretty quick. If you ran this locally on the machines it might be a second or so quicker since we are connecting remotely.
For the future, we are planning to add some JMX stuff to our actual application so we can monitor that as well. On the list are cache hits, requests per second, etc.
All together, it took me about 45 minutes to write this script and most of that was because I wasn’t familiar with the JMX api at all. After that I used JConsole to get the actual object names and property names, which was a big help.
Don’t miss anything, subscribe!
Did you enjoy this post? Why not leave a comment below and continue the conversation, or subscribe to my feed and get articles like this delivered automatically to your feed reader.
Comments
Do you like to show yourself in a particular way? Here I will bring you something very different and fashioned in ed-hardy.
Frome there you will find what you like and also you can choose what you like to buy, or maybe something you like we didn’t show on the net.Don’t worry ,We have the
good craftman to help you ,they have good skill and will make what you like in time .http://www.ed-hardy.cc/ ed hardy
Classic Tall Ugg Boots on sale!,We are professional supply Ugg bailey button ,Ugg classic short boots is your best choice,free shipping and nontax,only need 1 week to your door!
http://www.uggboots-site.com/ fashion ugg boots
It’s not very easy to hear facts referring to this good postand essays writers can propose to buy an essay to get correct facts and that is manageable to buy custom papers per very reduced costs!
0314This kind of new Nike air max light function a series of black, golden color, with white material, above, and in entire only. The athletic shoes mostly are in the black voice gold person who has rendered meritorious service and the white fender following nearly perfect white the bottom use the black and the golden color shoe sole.air max 90″>air max 90 – White/Black. Chooses these present to extend, your on-line store. This kind of new Air max 95 light function a series of black, golden color, with white material, above, and in entire only. The athletic shoes mostly are in the black voice gold person who has rendered meritorious service and the white fender following nearly perfect white the bottom use the black and the golden color shoe sole. Chooses these present to extend, Air Max 2010
your on-line store
Deckers was established in 1973 and a pair of sandals. Since then, Teva Sandals became a popular style, although they were originally designed for airor. The uk ugg boots product range rose to several other footwear types, such as sneakers, and men’s and women’s casual shoes.uggs on sale was acquired by Deckers Outdoor Corporation in 1995,and by 1998 had expanded their line to a whopping ten models. It was in 2000, when daytime TV queen Oprah Winfrey acquired a pair ofugg bailey button, that their popularity started to skyrocket. She liked them so much she bought ugg classic cardy boots for her entire staff,and ugg classic tall boots really took off-in the process dragging all other major Ugg footwear brands along on its coattails.
The classic and euro hiker lines of classic timberland boots can be chosen in a plum and pink color scheme that is undoubtedly the showiest design of Timberland Roll Top any ankle-high winter boot anywhere. The decision to buy Timberland 6 boots will continue to be influenced by the weather, but the influence of fashion has made its mark on Cheap timberland boots that will likely remain for many years to come.

I’m curious to know why you didn’t use GroovyMBean?
Otherwise, great and interesting article!