<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Shell Tips ! &#187; Java</title>
	<atom:link href="http://www.shell-tips.com/category/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.shell-tips.com</link>
	<description>Some useful tips about CLI tools, Shell scripts and batch files... GNU Bash, Windows XP, SQL, Help Sheets / Cheat Sheets, etc.</description>
	<lastBuildDate>Mon, 14 Jun 2010 08:56:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Graphing Java JMX Object values with Ganglia and Python using JPype</title>
		<link>http://www.shell-tips.com/2010/05/31/graphing-java-jmx-object-values-with-ganglia-and-python-using-jpype/</link>
		<comments>http://www.shell-tips.com/2010/05/31/graphing-java-jmx-object-values-with-ganglia-and-python-using-jpype/#comments</comments>
		<pubDate>Mon, 31 May 2010 10:00:54 +0000</pubDate>
		<dc:creator>Nicolas Brousse</dc:creator>
				<category><![CDATA[Case Study]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Ganglia]]></category>
		<category><![CDATA[graphing]]></category>
		<category><![CDATA[JMX]]></category>
		<category><![CDATA[JPype]]></category>
		<category><![CDATA[monitoring]]></category>

		<guid isPermaLink="false">http://www.shell-tips.com/?p=157</guid>
		<description><![CDATA[With Ganglia, graphing a large number of servers has never been so easy&#8230; Ganglia is a scalable distributed monitoring system for high-performance computing systems such as clusters and Grids. Ganglia let you create any kind of module in C/C++ or Python. You can also use the command line tool Gmetric and then the scripting language [...]]]></description>
			<content:encoded><![CDATA[<p>With <a title="Ganglia SF.net" href="http://ganglia.sourceforge.net" target="_self">Ganglia</a>, graphing a large number of servers has never been so easy&#8230; <em>Ganglia is a scalable distributed monitoring system for high-performance  computing systems such as clusters and Grids.</em> Ganglia let you create any kind of module in C/C++ or Python. You can also use the command line tool <a title="Gmetric Scripts" href="http://ganglia.sourceforge.net/gmetric" target="_self">Gmetric</a> and then the scripting language of your choice. The problem with Gmetrics is that you can&#8217;t keep your data organized by group and it&#8217;s getting harder to poll values in an efficient way. Few months ago I needed to monitor some <a title="JMX on Wikipedia" href="http://en.wikipedia.org/wiki/Java_Management_Extensions" target="_self">JMX</a> values returned by a Java daemon.</p>
<p><span id="more-157"></span></p>
<p>This post is quite succinct as I consider you already know Ganglia, Python and Java.</p>
<p>To monitor Java JMX values with Ganglia, I used <a title="JPype on SF.net" href="http://jpype.sourceforge.net" target="_self">JPype</a>. <em>JPype is an effort to allow python programs full access to java class libraries.</em> This allowed me to port easily the JMX <a title="Munin Project" href="http://munin-monitoring.org" target="_self">Munin</a> plugin, you can get this plugin on <a title="Munin Exchange" href="http://su.pr/2BxAab" target="_self">Munin Exchange</a>. The port, is really basic as I just converted few method to make sure I can publicly access them from the Python module. You can take a look at the <a href="http://www.shell-tips.com/wp-content/uploads/jmxquery.patch.txt">jmxquery.patch</a> or download <a href="http://www.shell-tips.com/wp-content/uploads/jmxquery.jar_.tar.gz">jmxquery.jar</a>.</p>
<pre class="brush:diff">diff -urBN jmxquery.a/src/jmxquery/src/org/munin/JMXQuery.java jmxquery.b/src/jmxquery/src/org/munin/JMXQuery.java
--- jmxquery.a/src/jmxquery/src/org/munin/JMXQuery.java	2007-05-14 01:07:44.000000000 -0700
+++ jmxquery.b/src/jmxquery/src/org/munin/JMXQuery.java	2010-01-15 15:40:00.000000000 -0800
@@ -61,7 +61,7 @@
 		this.password = password;
 	}

-	private void connect() throws IOException
+	public void connect() throws IOException
 	{
 		Map environment = null;
 		if (username != null &amp;&amp; password != null)
@@ -78,7 +78,18 @@
 		connection = connector.getMBeanServerConnection();
 	}

-	private void list() throws IOException, InstanceNotFoundException, IntrospectionException, ReflectionException
+	public void ping() throws IOException
+	{
+	  try {
+	    MBeanServerConnection testConnection = connector.getMBeanServerConnection();
+	    if (testConnection == null)
+	       this.connect();
+	  } catch (IOException e) {
+	    this.connect();
+	  }
+	}
+
+	public void list() throws IOException, InstanceNotFoundException, IntrospectionException, ReflectionException
 	{
 		if (config == null)
 		{
@@ -90,7 +101,7 @@
 		}
 	}

-	private void listConfig()
+	public void listConfig()
 	{
 		for (FieldProperties field : config.getFields())
 		{
@@ -107,7 +118,22 @@
 		}
 	}

-	private void output(String name, Object attr, String key)
+	public String output(String name, String JmxObjectName, String JmxAttributeName, String Key)
+	{
+    try
+    {
+      Object value = connection.getAttribute(new ObjectName(JmxObjectName), JmxAttributeName);
+      return output(name, value, Key);
+    }
+    catch (Exception e)
+    {
+      System.err.println("Fail to output " + name);
+      e.printStackTrace();
+    }
+    return null;
+	}
+
+	public String output(String name, Object attr, String key)
 	{
 		if (attr instanceof CompositeDataSupport)
 		{
@@ -116,15 +142,17 @@
 			{
 				throw new IllegalArgumentException("Key is null for composed data " + name);
 			}
-			System.out.println(name + ".value " + format(cds.get(key)));
+			//System.out.println(name + ".value " + format(cds.get(key)));
+			return format(cds.get(key));
 		}
 		else
 		{
-			System.out.println(name + ".value " + format(attr));
+			//System.out.println(name + ".value " + format(attr));
+		  return format(attr);
 		}
 	}

-	private void output(String name, Object attr)
+	public void output(String name, Object attr)
 	{
 		if (attr instanceof CompositeDataSupport)
 		{
@@ -142,7 +170,7 @@
 	}

 	@SuppressWarnings("unchecked")
-	private void listAll() throws IOException, InstanceNotFoundException, IntrospectionException, ReflectionException
+	public void listAll() throws IOException, InstanceNotFoundException, IntrospectionException, ReflectionException
 	{
 		Set<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="100" height="100" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><embed type="application/x-shockwave-flash" width="100" height="100"></embed></object></pre>
<p>Once JPype is installed, make sure your Ganglia is configured with the python module.</p>
<pre class="brush:text"># The modules section describes the module
#  that should be loaded.
#   name - module name
#   path - load path of the .so
#   params - path to the directory where mod_python
#             should look for python metric modules
modules {
  module {
    name = "python_module"
    path = "modpython.so"
    params = "/opt/ganglia/python_modules"
  }
}

include ('/opt/ganglia/etc/conf.d/*.pyconf')
</pre>
<p>Then you can use this basic <a href="http://www.shell-tips.com/wp-content/uploads/jmx.py_.txt">jmx python</a> module:</p>
<pre class="brush:python">"""
Ganglia Module to graph JMX values using JPype
Author: Nicolas Brousse
"""
from jpype import *

import os, platform, sys, time

debug = 0

_jmx = None
_jmx_cur_status = {}
_jmx_pre_status = {}
_jmx_pre_time = {}
_eta = 0
_jmx_params = {'User': '',
              'Password': '',
              'Host': '127.0.0.1',
              'Port': '8989',
              'JMXWrapper': '/opt/ganglia/jmxquery.jar'}

descriptors = []

gauge_metrics = {}

def Metric_Handler(name):
    global _jmx

    if _jmx is None:
        _jmx = initJVM()

    pre = None
    cur = 0
    eta = 0

    if debug:
        print "[ DEBUG ] _jmx_cur_status length: %d" % len(_jmx_cur_status)
        print "[ DEBUG ] _jmx_pre_status length: %d" % len(_jmx_pre_status)

    if _jmx is None:
        raise TypeError("No valid JMX Object !")

    if name in _jmx_cur_status:
        _jmx_pre_status[name] = _jmx_cur_status[name]

    for d in descriptors:
        if d['name'] == name:
            break

    try:
        if "jmxKeyName" in d:
            key = d['jmxKeyName']
        else:
            key = None

        if debug:
            print "[ DEBUG ] _jmx.output(%s, %s, %s, %s)" % \
                (d['name'], d['jmxObjectName'], d['jmxAttributeName'], key)

        _jmx.ping()
        result = _jmx.output(d['name'], d['jmxObjectName'], d['jmxAttributeName'], key)
    except:
        print "Error: ", sys.exc_info()[1]
        raise

    if result.isdigit():
        if debug: print "[ DEBUG ] %s: %s" % (name, result)
        _jmx_cur_status[name] = result

        cur_time = time.time()
        if name in _jmx_pre_time:
            eta = cur_time - _jmx_pre_time[name]
            if debug:
                print '[ DEBUG ] ETA: %d, Last time: %d, Cur time: %d' % (eta, _jmx_pre_time[name], cur_time)

        _jmx_pre_time[name] = cur_time

    if name in _jmx_cur_status:
        cur = _jmx_cur_status[name]
    else:
        cur = 0
    if len(_jmx_pre_status) &gt; 0 and name in _jmx_pre_status:
        pre = _jmx_pre_status[name]
    else:
        pre = 0
    eta = int(eta)

    if name in gauge_metrics:
        if pre is not None and eta &gt; 0:
            ret = (long(cur) - long(pre)) / eta
        else:
            ret = 0
    else:
        ret = cur

    if debug:
        print "[ DEBUG ] Metric_Handler(%s): %s (eta: %s, cur: %s, pre: %s)" % (name, ret, eta, cur, pre)

    return long(ret)

def Init_Metric (name, jmxObjectName, jmxAttributeName, jmxKeyName, tmax, type, slope, units, fmt, handler):
    '''Create a metric definition dictionary object.'''
    d = {'name': name.lower(),
        'jmxObjectName': jmxObjectName,
        'jmxAttributeName': jmxAttributeName,
        'jmxKeyName': jmxKeyName,
        'call_back': handler,
        'time_max': tmax,
        'value_type': type,
        'units': units,
        'slope': slope,
        'format': fmt,
        'description': 'JMX '+name.replace("_"," "),
	    'groups': 'jmx'}
    return d

def metric_init(params):
    global _jmx, _jmx_params

    if debug: print "[ DEBUG ] metric_init()"

    if 'User' in params:
        _jmx_params['User'] = params['User']

    if 'Password' in params:
        _jmx_params['Password'] = params['Password']

    if 'Host' in params:
        _jmx_params['Host'] = params['Host']

    if 'Port' in params:
        _jmx_params['Port'] = int(params['Port'])

    if 'JMXWrapper' in params:
        _jmx_params['JMXWrapper'] = params['JMXWrapper']

    return descriptors

def initJVM():
    if debug: print "[ DEBUG ] initJVM()"

    if platform.architecture()[0] == "32bit":
        arch="i386"
    else:
        arch="amd64"

    jvm="/usr/java/jdk/jre/lib/%s/client/libjvm.so" % arch
    if not os.path.isfile(jvm):
        jvm="/usr/java/jdk/jre/lib/%s/server/libjvm.so" % arch
        if not os.path.isfile(jvm):
            raise IOError("Can't find the libjvm.so (%s)" % jvm)

    if not os.path.isfile(_jmx_params['JMXWrapper']):
        raise IOError("Can't find the JMX Wrapper at'%s'" % \
            _jmx_params['JMXWrapper'])

    try:
        startJVM(jvm, "-Djava.class.path=%s" % _jmx_params['JMXWrapper'])

        url = "service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi" % \
               (_jmx_params['Host'], int(_jmx_params['Port']))

        JMXQuery = JClass("org.munin.JMXQuery")

        if _jmx_params['Password'] is not '':
            _jmx = JMXQuery(url, username, password)
        else:
            _jmx = JMXQuery(url)

        _jmx.connect()
    except:
        print "Error: ", sys.exc_info()[1]
        raise

    return _jmx

def metric_cleanup():
    '''Clean up the metric module.'''
    #shutdownJVM()

def Build_Conf():
    print "modules {\n module {\n  name = \"jmx\"\n  language = \"python\"\n }\n}\n"
    print "collection_group {\n collect_every = 30\n time_threshold = 60"
    for d in descriptors:
        print " metric {\n  name = \""+d['name']+"\"\n  title = \""+d['description']+"\"\n  value_threshold = 1.0\n }"
    print "}\n"

descriptors.append(
    Init_Metric("java_cpu_time", "java.lang:type=Threading", "CurrentThreadCpuTime", "",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("java_cpu_user_time", "java.lang:type=Threading", "CurrentThreadUserTime", "",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("java_memory_nonheap_committed", "java.lang:type=Memory", "NonHeapMemoryUsage", "committed",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("java_memory_nonheap_max", "java.lang:type=Memory", "NonHeapMemoryUsage", "max",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("java_memory_nonheap_used", "java.lang:type=Memory", "NonHeapMemoryUsage", "used",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("java_memory_heap_committed", "java.lang:type=Memory", "HeapMemoryUsage", "committed",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("java_memory_heap_used", "java.lang:type=Memory", "HeapMemoryUsage", "used",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("java_memory_heap_max", "java.lang:type=Memory", "HeapMemoryUsage", "max",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("os_memory_physical", "java.lang:type=OperatingSystem", "FreePhysicalMemorySize", "",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("os_memory_vm", "java.lang:type=OperatingSystem", "CommittedVirtualMemorySize", "",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("java_thread_count", "java.lang:type=Threading", "ThreadCount", "",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))
descriptors.append(
    Init_Metric("java_thread_count_peak", "java.lang:type=Threading", "PeakThreadCount", "",
        int(300), 'uint', 'both', '', '%u', Metric_Handler))

#This code is for debugging and unit testing
if __name__ == '__main__':
    try:
        if len(sys.argv) &lt;= 1:
            debug = 1

        metric_init(_jmx_params)

        if len(sys.argv) &lt;= 1:
            while True:
                for d in descriptors:
                    v = d['call_back'](d['name'])
                time.sleep(5)
        elif sys.argv[1] == "config":
            Build_Conf()
            metric_cleanup()

    except KeyboardInterrupt:
        print "Process interrupted."
        if _JMX_WorkerThread.running and not _JMX_WorkerThread.shuttingdown:
            _JMX_WorkerThread.shutdown()
        time.sleep(0.2)
        sys.exit(1)
</pre>
<p>You can simply run &#8220;<em>python jmx.py config</em>&#8221; to generate the jmx.pyconf file. Also, you&#8217;d probably need to edit the plugin to check for your own JMX values. A lot of improvement could be done to this plugin, but all the basics are there and it can give you some awesome graph to monitor your Java application.</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F&amp;title=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F&amp;title=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F&amp;title=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F&amp;headline=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype&amp;u=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F&amp;title=Graphing+Java+JMX+Object+values+with+Ganglia+and+Python+using+JPype&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fwww.shell-tips.com%2F2010%2F05%2F31%2Fgraphing-java-jmx-object-values-with-ganglia-and-python-using-jpype%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://www.shell-tips.com/2010/05/31/graphing-java-jmx-object-values-with-ganglia-and-python-using-jpype/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JETM &#8211;  The easy way to monitor your Spring Application</title>
		<link>http://www.shell-tips.com/2009/06/08/jetm-the-easy-way-to-monitor-your-spring-application/</link>
		<comments>http://www.shell-tips.com/2009/06/08/jetm-the-easy-way-to-monitor-your-spring-application/#comments</comments>
		<pubDate>Mon, 08 Jun 2009 08:10:49 +0000</pubDate>
		<dc:creator>Nicolas Brousse</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[bean]]></category>
		<category><![CDATA[benchmark]]></category>
		<category><![CDATA[jetm]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[red5]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.shell-tips.com/?p=47</guid>
		<description><![CDATA[JETM stand for Java™ Execution Time Measurement Library, it&#8217;s an useful library to monitor your java application in a smart and easy way. Here is an overview on how to use JETM with a Spring application like in Red5. I will consider that you have a running Red5 server and you know how a Red5 [...]]]></description>
			<content:encoded><![CDATA[<p>JETM stand for <em>Java™ Execution Time Measurement Library</em>, it&#8217;s an useful library to monitor your java application in a smart and easy way. Here is an overview on how to use <a title="JETM" href="http://jetm.void.fm">JETM</a> with a <a title="Spring" href="http://www.springsource.org">Spring</a> application like in <a title="Red5" href="http://osflash.org/red5">Red5</a>.</p>
<p><span id="more-47"></span>I will consider that you have a running Red5 server and you know how a Red5 application work. It&#8217;s quite easy to install, just have a look there if you need : <a title="Red5 Help" href="http://osflash.org/red5/help">http://osflash.org/red5/help</a></p>
<h3><span style="text-decoration: underline;"><strong>The Spring DTD based configuration</strong></span></h3>
<p>Here is the power of Spring, <a title="Aspect Oriented Programming" href="http://en.wikipedia.org/wiki/Aspect-oriented_programming">AOP</a> and the Beans. In your Red5 installation copy the JETM jar file to the lib directory, then edit the conf/red5-common.xml as following :</p>
<pre class="brush:xml">&lt;bean id="etmMonitor"
class="etm.core.monitor.NestedMonitor"
init-method="start" destroy-method="stop"/&gt;

&lt;bean id="etmHttpConsole"
class="etm.contrib.console.HttpConsoleServer"
init-method="start" destroy-method="stop" autowire="constructor"/&gt;</pre>
<p>Those two new beans are there to instantiate the JETM monitor and activate the HTTP console, by default the JETM console listen on port 40000.</p>
<p>So, at this point if you run your red5 server you will just see two new line in your logs :</p>
<pre class="brush:text">7 juin 2009 19:48:36 etm.core.monitor.EtmMonitorSupport start
INFO: JETM 1.2.3 started.</pre>
<p>Now, we need to define which services we want to track. For example, on the oflaDemo application, we can track what&#8217;s going on  by simply adding those other beans to this config file : oflaDemo/WEB-INF/red5-web.xml</p>
<pre class="brush:xml">&lt;bean id="etmMethodCallInterceptor"
class="etm.contrib.aop.aopalliance.EtmMethodCallInterceptor"
autowire="constructor"/&gt;

&lt;bean id="etmAutoProxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"&gt;

&lt;property name="interceptorNames"&gt;
&lt;list&gt;
&lt;value&gt;etmMethodCallInterceptor&lt;/value&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;property name="beanNames"&gt;
&lt;value&gt;web.*&lt;/value&gt;
&lt;/property&gt;

&lt;/bean&gt;</pre>
<p>From now, we are monitoring all the web.* bean from oflaDemo, this means, if you connect to oflaDemo (http://localhost:5080/demos/ofla_demo.html), view a stream etc, then go to the console (http://localhost:40000) you will see some interesting statistics like the average time spend in your Application start method etc.</p>
<div class="wp-caption alignnone" style="width: 551px"><img class="  " title="JETM Console" src="/dl/jetm-console.jpg" alt="JETM Console - Red5 with oflaDemo" width="541" height="520" /><p class="wp-caption-text">JETM Console - Red5 with oflaDemo</p></div>
<h3><strong><span style="text-decoration: underline;">The programmatic way</span></strong></h3>
<p>If you need more detailed statistics you can implement the lib in your application. It&#8217;s what I do now as I can have better detail and select what I really want to track, also you can manage all the JETM configuration thru an xml file. To do that you just need to change your web.handler bean definition to call an init method and implement this method in your application.</p>
<p>In MyTest/WEB-INF/red5-web.xml :</p>
<pre class="brush:xml">&lt;bean id="web.handler"
class="org.example.red5.MyTestApplication"
init-method="init" singleton="true"&gt;</pre>
<p>Then implement the init method in MyTestApplication :</p>
<pre class="brush:java">private EtmMonitor profiler = EtmManager.getEtmMonitor();

public void init()
throws URISyntaxException
{
log.debug("Application initialized: {}", getClass().getName());

URL url = getClass().getClassLoader().getResource("jetm-mytest.xml");
try {
XmlEtmConfigurator.configure(new FileInputStream(url.getPath()));
if (!profiler.isStarted())
profiler.start();
} catch (FileNotFoundException fne) {
log.warn(fne.getMessage());
}
}</pre>
<p>Add the jetm-mytest.xml file in your classpath like in red5/conf or in MyTest/WEB-INF/lib. The xml file look like something like that :</p>
<pre class="brush:xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE jetm-config PUBLIC "-// void.fm //DTD JETM Config 1.2//EN"
"http://jetm.void.fm/dtd/jetm_config_1_2.dtd"&gt;

&lt;jetm-config timer="sun"&gt;

&lt;aggregator-chain&gt;

&lt;chain-element class="etm.core.aggregation.BufferedTimedAggregator"&gt;
&lt;!-- Set aggregation interval to 1 second --&gt;
&lt;property name="aggregationInterval"&gt;1000&lt;/property&gt;
&lt;/chain-element&gt;

&lt;chain-element class="etm.contrib.aggregation.log.CommonsLoggingAggregator"&gt;
&lt;!-- Set commons-logging log category --&gt;
&lt;property name="logName"&gt;etm-result&lt;/property&gt;
&lt;/chain-element&gt;

&lt;chain-root class="etm.core.aggregation.persistence.PersistentRootAggregator"&gt;
&lt;property name="aggregationInterval"&gt;10000&lt;/property&gt;
&lt;/chain-root&gt;

&lt;/aggregator-chain&gt;

&lt;extension&gt;
&lt;plugin class="etm.contrib.console.HttpConsoleServerPlugin"&gt;
&lt;property name="listenPort"&gt;40000&lt;/property&gt;
&lt;property name="expanded"&gt;true&lt;/property&gt;
&lt;property name="worker-size"&gt;3&lt;/property&gt;
&lt;/plugin&gt;
&lt;/extension&gt;

&lt;/jetm-config&gt;</pre>
<p>That&#8217;s it, now when you want to collect the statistic in one of your method or in a specific process you can just do something like that :</p>
<pre class="brush:java">public void MyMethod() {

EtmPoint point = profiler.createPoint(getClass().getName()+"#MyMethod");

... Your stuff ...

point.collect();

}</pre>
<p>All this is a succinct introduction, you can go further and do some amazing things. JETM is a really powerful tool to improve your application performance.</p>
<div class="lightsocial_container"><a class="lightsocial_a" href="http://digg.com/submit?url=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F&amp;title=JETM+-++The+easy+way+to+monitor+your+Spring+Application" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/digg.png" alt="Digg This" title="Digg This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.reddit.com/submit?url=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F&amp;title=JETM+-++The+easy+way+to+monitor+your+Spring+Application" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/reddit.png" alt="Reddit This" title="Reddit This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.stumbleupon.com/submit?url=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F&amp;title=JETM+-++The+easy+way+to+monitor+your+Spring+Application" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/stumbleupon.png" alt="Stumble Now!" title="Stumble Now!" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://buzz.yahoo.com/buzz?targetUrl=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F&amp;headline=JETM+-++The+easy+way+to+monitor+your+Spring+Application" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/yahoo_buzz.png" alt="Buzz This" title="Buzz This" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dzone.com/links/add.html?title=JETM+-++The+easy+way+to+monitor+your+Spring+Application&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/dzone.png" alt="Vote on DZone" title="Vote on DZone" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.facebook.com/sharer.php?t=JETM+-++The+easy+way+to+monitor+your+Spring+Application&amp;u=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/facebook.png" alt="Share on Facebook" title="Share on Facebook" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://delicious.com/save?title=JETM+-++The+easy+way+to+monitor+your+Spring+Application&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/delicious.png" alt="Bookmark this on Delicious" title="Bookmark this on Delicious" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.dotnetkicks.com/kick/?title=JETM+-++The+easy+way+to+monitor+your+Spring+Application&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/dotnetkicks.png" alt="Kick It on DotNetKicks.com" title="Kick It on DotNetKicks.com" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://dotnetshoutout.com/Submit?title=JETM+-++The+easy+way+to+monitor+your+Spring+Application&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/dotnetshoutout.png" alt="Shout it" title="Shout it" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.linkedin.com/shareArticle?mini=true&amp;url=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F&amp;title=JETM+-++The+easy+way+to+monitor+your+Spring+Application&amp;summary=&amp;source=" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/linkedin.png" alt="Share on LinkedIn" title="Share on LinkedIn" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.technorati.com/faves?add=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/technorati.png" alt="Bookmark this on Technorati" title="Bookmark this on Technorati" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://twitter.com/home?status=Reading+http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/twitter.png" alt="Post on Twitter" title="Post on Twitter" /></a>&nbsp;&nbsp;<a class="lightsocial_a" href="http://www.google.com/buzz/post?url=http%3A%2F%2Fwww.shell-tips.com%2F2009%2F06%2F08%2Fjetm-the-easy-way-to-monitor-your-spring-application%2F" ><img class="lightsocial_img" src="http://www.shell-tips.com/wp-content/plugins/light-social/google_buzz.png" alt="Google Buzz (aka. Google Reader)" title="Google Buzz (aka. Google Reader)" /></a>&nbsp;&nbsp;</div>]]></content:encoded>
			<wfw:commentRss>http://www.shell-tips.com/2009/06/08/jetm-the-easy-way-to-monitor-your-spring-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
