Last updated:

👉 This post was initially written in 2009 and referred to specific software versions. When tunning your system, always consider which version you are running. Information below may be outdated. Use it at your own risk.

JETM stand for Java™ Execution Time Measurement Library, it is 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.

This post consider that you have a running Red5 server and you know how a Red5 application work. It is quite easy to install, just have a look there if you need: http://osflash.org/red5/help

The Spring DTD based configuration

Here is the power of Spring, AOP 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 :

<bean id="etmMonitor"
class="etm.core.monitor.NestedMonitor"
init-method="start" destroy-method="stop"/>

<bean id="etmHttpConsole"
class="etm.contrib.console.HttpConsoleServer"
init-method="start" destroy-method="stop" autowire="constructor"/>

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.

So, at this point if you run your red5 server you will just see two new line in your logs:

7 juin 2009 19:48:36 etm.core.monitor.EtmMonitorSupport start
INFO: JETM 1.2.3 started.

Now, we need to define which services we want to track. For example, on the oflaDemo application, we can track what’s going on  by simply adding those other beans to this config file: oflaDemo/WEB-INF/red5-web.xml

<bean id="etmMethodCallInterceptor"
class="etm.contrib.aop.aopalliance.EtmMethodCallInterceptor"
autowire="constructor"/>

<bean id="etmAutoProxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

<property name="interceptorNames">
<list>
<value>etmMethodCallInterceptor</value>
</list>
</property>
<property name="beanNames">
<value>web.*</value>
</property>

</bean>

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.

JETM Console - Red5 with oflaDemo

The programmatic way

If you need more detailed statistics you can implement the lib in your application. It’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 throughan 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.

In MyTest/WEB-INF/red5-web.xml :

<bean id="web.handler"
class="org.example.red5.MyTestApplication"
init-method="init" singleton="true">

Then implement the init method in MyTestApplication :

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());
  }
}

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 :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jetm-config PUBLIC "-// void.fm //DTD JETM Config 1.2//EN"
"http://jetm.void.fm/dtd/jetm_config_1_2.dtd">

<jetm-config timer="sun">

<aggregator-chain>

<chain-element class="etm.core.aggregation.BufferedTimedAggregator">
<!-- Set aggregation interval to 1 second -->
<property name="aggregationInterval">1000</property>
</chain-element>

<chain-element class="etm.contrib.aggregation.log.CommonsLoggingAggregator">
<!-- Set commons-logging log category -->
<property name="logName">etm-result</property>
</chain-element>

<chain-root class="etm.core.aggregation.persistence.PersistentRootAggregator">
<property name="aggregationInterval">10000</property>
</chain-root>

</aggregator-chain>

<extension>
<plugin class="etm.contrib.console.HttpConsoleServerPlugin">
<property name="listenPort">40000</property>
<property name="expanded">true</property>
<property name="worker-size">3</property>
</plugin>
</extension>

</jetm-config>

That’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 :

public void MyMethod() {

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

... Your stuff ...

point.collect();

}

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.