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