User: danch
Date: 01/04/03 21:49:52
Added: src/main/org/jboss/util CounterInterceptor.java
CounterService.java CounterServiceMBean.java
Log:
MBean and interceptor to allow statistics gathering on time spent in EJB methods
Revision Changes Path
1.1 jboss/src/main/org/jboss/util/CounterInterceptor.java
Index: CounterInterceptor.java
===================================================================
package org.jboss.util;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.jboss.ejb.MethodInvocation;
import org.jboss.ejb.Container;
import org.jboss.ejb.plugins.*;
import org.jboss.logging.Logger;
import org.jboss.util.CounterService;
/**
* Interceptor that uses the CounterService MBean to record the length of time
* spent in 'lower' interceptors (below it in the stack).
* <p><b>How to use:</b></p>
* <p>First, the CounterService MBean must be installed in JBoss. To do this,
* place the following in your JBoss.jcml file, near the very end.</p>
* <code>
* <mbean code="org.jboss.util.CounterService"
name="DefaultDomain:service=CounterService" > </mbean>
* </code>
* <p>This will start up and enable the centralized counter in your JBoss server
* instance.
* <p>Next, you need to configure this interceptor into the interceptor stacks
* of any beans you wish to monitor. This can be done either globally for a
* container-config in standardjboss.xml, or on a per-bean basis in a jar's
* jboss.jcml. Just insert the following at the top of the
<container-interceptors>
* section. If you're overriding this for a bean in jboss.xml, you'll need to
* override the entire container-interceptors section.</p>
* <code>
* <interceptor>org.jboss.util.CounterInterceptor</interceptor>
* </code>
* <p>This can go anywhere in the container-interceptors section, but either
* the top or the bottom will probably be best for gathering application
* statistics.
* @author <a href="mailto:[EMAIL PROTECTED]">Dan Christopherson</href>
*/
public class CounterInterceptor extends AbstractInterceptor {
Container container = null;
CounterService counter = null;
boolean loggedNoCounter = false;
StringBuffer baseCounterName = null;
int baseNameLength = 0;
public CounterInterceptor() {
}
public void setContainer(Container container) {
baseCounterName = new StringBuffer(container.getBeanClass().getName());
baseNameLength = baseCounterName.length();
this.container = container;
}
public Container getContainer() {
return container;
}
public Object invokeHome(MethodInvocation mi) throws Exception {
long startTime=System.currentTimeMillis();
try {
return super.invokeHome(mi);
} finally {
if (getCounter() != null) {
long endTime=System.currentTimeMillis();
baseCounterName.append("Home.");
baseCounterName.append(mi.getMethod().getName());
counter.accumulate(baseCounterName.toString(), endTime-startTime);
baseCounterName.setLength(baseNameLength);
}
}
}
public Object invoke(MethodInvocation mi) throws Exception {
long startTime=System.currentTimeMillis();
try {
return super.invoke(mi);
} finally {
if (getCounter() != null) {
long endTime=System.currentTimeMillis();
baseCounterName.append('.');
baseCounterName.append(mi.getMethod().getName());
counter.accumulate(baseCounterName.toString(), endTime-startTime);
baseCounterName.setLength(baseNameLength);
}
}
}
public void init() throws java.lang.Exception {
//get a reference to the CounterService from JNDI
Logger.debug("CounterInterceptor initializing");
}
private CounterService getCounter() {
if (counter == null) {
try {
InitialContext ctx = new InitialContext();
counter = (CounterService)ctx.lookup("java:/CounterService");
} catch (NamingException ne) {
if (!loggedNoCounter) {
Logger.warning("CounterInterceptor can't get counter service "+ne);
loggedNoCounter = true;
}
}
}
return counter;
}
}
1.1 jboss/src/main/org/jboss/util/CounterService.java
Index: CounterService.java
===================================================================
package org.jboss.util;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import org.jboss.util.ServiceMBeanSupport;
import org.jboss.logging.Log;
import org.jboss.naming.NonSerializableFactory;
/** A service offering accumulator style counters to help in diagnosing
* performance issues.
* @author <a href="mailto:[EMAIL PROTECTED]">Dan Christopherson</href>
* */
public class CounterService
extends ServiceMBeanSupport
implements CounterServiceMBean
{
private HashMap counterMap = new HashMap();
/** accumulate a count into a named counter. will initialize the named
* counter if neccessary. */
public void accumulate(String counterName, long add) {
Counter counter = null;
synchronized (counterMap) {
counter = (Counter)counterMap.get(counterName);
if (counter == null) {
counter = new Counter(counterName);
counterMap.put(counterName, counter);
}
}
counter.addToCount(add);
}
protected void startService() throws java.lang.Exception {
super.startService();
InitialContext ctx = new InitialContext();
//bind myself into JNDI, at java:/CounterService
NonSerializableFactory.bind("java:/CounterService", this);
StringRefAddr addr = new StringRefAddr("nns", "java:/CounterService");
Reference ref = new Reference(this.getClass().getName(), addr,
NonSerializableFactory.class.getName(), null);
ctx.bind("java:/CounterService", ref);
}
protected void stopService() {
super.stopService();
try {
InitialContext ctx = new InitialContext();
ctx.unbind("java:/CounterService");
NonSerializableFactory.unbind("java:/CounterService");
} catch (NamingException ne) {
log.error("Coulnd't unbind CounterService: "+ne.getMessage());
}
}
public String getName() {
return "Counter Service";
}
public String list() {
DecimalFormat format = new DecimalFormat("####0.0000");
String retVal = "";
Iterator keys = counterMap.keySet().iterator();
while (keys.hasNext()) {
String key = (String)keys.next();
Counter counter = (Counter)counterMap.get(key);
long total = 0;
int entries = 0;
synchronized (counter) {//so we dont catch half of it.
total = counter.getCount();
entries = counter.getEntries();
}
double avg = ((double)total)/((double)entries);
String descrip = key+": total="+total+" on "+entries+"entries for "+
"an average of "+format.format(avg)+"<br>\n";
retVal += descrip;
}
return retVal;
}
private static class Counter {
private String name;
private long count=0;
private int entries=0;
public Counter(String n) {
name = n;
}
public String getName() {
return name;
}
public synchronized long getCount() {
return count;
}
public synchronized int getEntries() {
return entries;
}
public synchronized void addToCount(long add) {
count += add;
entries++;
}
}
}
1.1 jboss/src/main/org/jboss/util/CounterServiceMBean.java
Index: CounterServiceMBean.java
===================================================================
package org.jboss.util;
import java.util.Vector;
/**
* MBean interface for the CounterService.
* @author <a href="mailto:[EMAIL PROTECTED]">Dan Christopherson</href>
*/
public interface CounterServiceMBean
extends org.jboss.util.ServiceMBean
{
public String list();
}
_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development