User: simone
Date: 00/12/18 02:21:48
Modified: src/main/org/jboss/ejb/plugins
LRUEnterpriseContextCachePolicy.java
AbstractInstanceCache.java
Log:
Added JMX and JMS monitoring code.
Revision Changes Path
1.6 +190 -23
jboss/src/main/org/jboss/ejb/plugins/LRUEnterpriseContextCachePolicy.java
Index: LRUEnterpriseContextCachePolicy.java
===================================================================
RCS file:
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/LRUEnterpriseContextCachePolicy.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- LRUEnterpriseContextCachePolicy.java 2000/12/12 09:45:32 1.5
+++ LRUEnterpriseContextCachePolicy.java 2000/12/18 10:21:47 1.6
@@ -7,6 +7,9 @@
package org.jboss.ejb.plugins;
import java.util.HashMap;
+import javax.jms.Message;
+import javax.jms.JMSException;
+
import org.jboss.util.LRUCachePolicy;
import org.jboss.util.TimerTask;
import org.jboss.ejb.DeploymentException;
@@ -15,15 +18,18 @@
import org.jboss.metadata.MetaData;
import org.w3c.dom.Element;
+import org.jboss.monitor.Monitorable;
+import org.jboss.monitor.client.BeanCacheSnapshot;
+
/**
* Least Recently Used cache policy for EnterpriseContexts.
*
* @see EnterpriseInstanceCache
* @author Simone Bordet ([EMAIL PROTECTED])
- * @version $Revision: 1.5 $
+ * @version $Revision: 1.6 $
*/
public class LRUEnterpriseContextCachePolicy extends LRUCachePolicy
- implements EnterpriseContextCachePolicy, XmlLoadable
+ implements EnterpriseContextCachePolicy, XmlLoadable, Monitorable
{
// Constants -----------------------------------------------------
@@ -47,6 +53,8 @@
private TimerTask m_overager;
/* The resizer timer task */
private TimerTask m_resizer;
+ /* Useful for log messages */
+ private StringBuffer m_buffer = new StringBuffer();
// Static --------------------------------------------------------
@@ -64,6 +72,20 @@
// Public --------------------------------------------------------
+ // Monitorable implementation ------------------------------------
+ public void sample(Object s)
+ {
+ BeanCacheSnapshot snapshot = (BeanCacheSnapshot)s;
+ LRUList list = getList();
+ synchronized (m_cache.getCacheLock())
+ {
+ snapshot.m_cacheMinCapacity = list.m_minCapacity;
+ snapshot.m_cacheMaxCapacity = list.m_maxCapacity;
+ snapshot.m_cacheCapacity = list.m_capacity;
+ snapshot.m_cacheSize = list.m_count;
+ }
+ }
+
// Z implementation ----------------------------------------------
public void start() throws Exception
{
@@ -172,16 +194,38 @@
// Protected -----------------------------------------------------
protected LRUList createList() {return new ContextLRUList();}
- protected LRUCacheEntry createCacheEntry(Object key, Object value)
- {
- return new ContextLRUEntry(key, value);
- }
+
protected void ageOut(LRUCacheEntry entry)
{
if (entry == null) {throw new IllegalArgumentException("Cannot remove
a null cache entry");}
- // Logger is very time expensive. Turn on only for debug
-// log.debug("Aging out from cache bean " +
m_cache.getContainer().getBeanMetaData().getEjbName() + ", id = " + entry.m_key + ";
cache size = " + getList().m_count);
+ m_buffer.setLength(0);
+ m_buffer.append("Aging out from cache bean ");
+ m_buffer.append(m_cache.getContainer().getBeanMetaData().getEjbName());
+ m_buffer.append("with id = ");
+ m_buffer.append(entry.m_key);
+ m_buffer.append("; cache size = ");
+ m_buffer.append(getList().m_count);
+ log.debug(m_buffer.toString());
+
+ if (m_cache.isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = m_cache.createMessage(entry.m_key);
+ try
+ {
+ message.setStringProperty("TYPE", "CACHE");
+ message.setStringProperty("ACTIVITY", "AGE-OUT");
+ }
+ catch (JMSException x)
+ {
+ log.exception(x);
+ }
+
+ // Send JMS Message
+ m_cache.sendMessage(message);
+ }
+
// Debug code
// new Exception().printStackTrace();
// new CacheDumper().execute();
@@ -191,12 +235,30 @@
}
protected void cacheMiss()
{
- ContextLRUList list = getList();
+ LRUList list = getList();
++list.m_cacheMiss;
+
+ if (m_cache.isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = m_cache.createMessage(null);
+ try
+ {
+ message.setStringProperty("TYPE", "CACHE");
+ message.setStringProperty("ACTIVITY", "CACHE-MISS");
+ }
+ catch (JMSException x)
+ {
+ log.exception(x);
+ }
+
+ // Send JMS Message
+ m_cache.sendMessage(message);
+ }
}
// Private -------------------------------------------------------
- private ContextLRUList getList() {return (ContextLRUList)m_list;}
+ private LRUList getList() {return m_list;}
// For debug purposes
// private java.util.Map getMap() {return m_map;}
@@ -216,14 +278,14 @@
protected ResizerTask(long resizerPeriod)
{
super(resizerPeriod);
- m_message = "Resized cache for bean " +
m_cache.getContainer().getBeanMetaData().getEjbName() + ": old size = ";
+ m_message = "Resized cache for bean " +
m_cache.getContainer().getBeanMetaData().getEjbName() + ": old capacity = ";
m_buffer = new StringBuffer();
}
public void execute()
{
// For now implemented as a Cache Miss Frequency algorithm
- ContextLRUList list = getList();
+ LRUList list = getList();
// Sync with the cache, since it is accessed also by another
thread
synchronized (m_cache.getCacheLock())
@@ -251,14 +313,34 @@
list.m_cacheMiss = 0;
}
}
- private void log(int oldSize, int newSize)
+ private void log(int oldCapacity, int newCapacity)
{
m_buffer.setLength(0);
m_buffer.append(m_message);
- m_buffer.append(oldSize);
- m_buffer.append(", new size = ");
- m_buffer.append(newSize);
+ m_buffer.append(oldCapacity);
+ m_buffer.append(", new capacity = ");
+ m_buffer.append(newCapacity);
log.debug(m_buffer.toString());
+
+ if (m_cache.isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = m_cache.createMessage(null);
+ try
+ {
+ message.setStringProperty("TYPE", "RESIZER");
+ message.setIntProperty("OLD_CAPACITY",
oldCapacity);
+ message.setIntProperty("NEW_CAPACITY",
newCapacity);
+ message.setIntProperty("SIZE",
getList().m_count);
+ }
+ catch (JMSException x)
+ {
+ log.exception(x);
+ }
+
+ // Send JMS Message
+ m_cache.sendMessage(message);
+ }
}
}
/**
@@ -277,12 +359,12 @@
}
public void execute()
{
- ContextLRUList list = getList();
+ LRUList list = getList();
long now = System.currentTimeMillis();
synchronized (m_cache.getCacheLock())
{
- for (ContextLRUEntry entry =
(ContextLRUEntry)list.m_tail; entry != null; entry = (ContextLRUEntry)list.m_tail)
+ for (LRUCacheEntry entry = list.m_tail; entry != null;
entry = list.m_tail)
{
if (now - entry.m_time >= m_maxBeanAge)
{
@@ -314,14 +396,99 @@
m_buffer.append(" - Cache size = ");
m_buffer.append(count);
log.debug(m_buffer.toString());
+
+ if (m_cache.isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = m_cache.createMessage(key);
+ try
+ {
+ message.setStringProperty("TYPE", "OVERAGER");
+ message.setIntProperty("SIZE", count);
+ }
+ catch (JMSException x)
+ {
+ log.exception(x);
+ }
+
+ // Send JMS Message
+ m_cache.sendMessage(message);
+ }
}
}
- /* Dummy subclass to give visibility to the inner classes */
- protected class ContextLRUList extends LRUList {}
- /* Dummy subclass to give visibility to the inner classes */
- protected class ContextLRUEntry extends LRUCacheEntry
+
+ /**
+ * Subclass that send JMS messages on list activity events.
+ */
+ protected class ContextLRUList extends LRUList
{
- protected ContextLRUEntry(Object key, Object value) {super(key,
value);}
+ protected void entryAdded(LRUCacheEntry entry)
+ {
+ if (m_cache.isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = m_cache.createMessage(entry.m_key);
+ try
+ {
+ message.setStringProperty("TYPE", "CACHE");
+ message.setStringProperty("ACTIVITY", "ADD");
+ message.setIntProperty("CAPACITY", m_capacity);
+ message.setIntProperty("SIZE", m_count);
+ }
+ catch (JMSException x)
+ {
+ log.exception(x);
+ }
+
+ // Send JMS Message
+ m_cache.sendMessage(message);
+ }
+ }
+ protected void entryRemoved(LRUCacheEntry entry)
+ {
+ if (m_cache.isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = m_cache.createMessage(entry.m_key);
+ try
+ {
+ message.setStringProperty("TYPE", "CACHE");
+ message.setStringProperty("ACTIVITY",
"REMOVE");
+ message.setIntProperty("CAPACITY", m_capacity);
+ message.setIntProperty("SIZE", m_count);
+ }
+ catch (JMSException x)
+ {
+ log.exception(x);
+ }
+
+ // Send JMS Message
+ m_cache.sendMessage(message);
+ }
+ }
+ protected void capacityChanged(int oldCapacity)
+ {
+ if (m_cache.isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = m_cache.createMessage(null);
+ try
+ {
+ message.setStringProperty("TYPE", "CACHE");
+ message.setStringProperty("ACTIVITY",
"CAPACITY");
+ message.setIntProperty("OLD_CAPACITY",
oldCapacity);
+ message.setIntProperty("NEW_CAPACITY",
m_capacity);
+ message.setIntProperty("SIZE", m_count);
+ }
+ catch (JMSException x)
+ {
+ log.exception(x);
+ }
+
+ // Send JMS Message
+ m_cache.sendMessage(message);
+ }
+ }
}
/**
1.2 +220 -20 jboss/src/main/org/jboss/ejb/plugins/AbstractInstanceCache.java
Index: AbstractInstanceCache.java
===================================================================
RCS file:
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/AbstractInstanceCache.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbstractInstanceCache.java 2000/12/12 09:35:16 1.1
+++ AbstractInstanceCache.java 2000/12/18 10:21:47 1.2
@@ -13,8 +13,22 @@
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
+
import javax.ejb.EJBException;
+import javax.jms.Topic;
+import javax.jms.TopicPublisher;
+import javax.jms.TopicSession;
+import javax.jms.TopicConnection;
+import javax.jms.TopicConnectionFactory;
+import javax.jms.Message;
+import javax.jms.Session;
+import javax.jms.JMSException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.rmi.PortableRemoteObject;
+
import org.w3c.dom.Element;
+
import org.jboss.util.CachePolicy;
import org.jboss.util.Executable;
import org.jboss.util.WorkerQueue;
@@ -27,6 +41,8 @@
import org.jboss.metadata.MetaData;
import org.jboss.metadata.XmlLoadable;
import org.jboss.logging.Logger;
+import org.jboss.monitor.Monitorable;
+import org.jboss.monitor.client.BeanCacheSnapshot;
/**
* Base class for caches of entity and stateful beans. <p>
@@ -39,10 +55,10 @@
* </ul>
*
* @author Simone Bordet ([EMAIL PROTECTED])
- * @version $Revision: 1.1 $
+ * @version $Revision: 1.2 $
*/
public abstract class AbstractInstanceCache
- implements InstanceCache, XmlLoadable
+ implements InstanceCache, XmlLoadable, Monitorable
{
// Constants -----------------------------------------------------
@@ -57,12 +73,72 @@
private PassivationHelper m_passivationHelper;
/* Map that holds mutexes used to sync the passivation with other activities */
private Map m_lockMap = new HashMap();
+ /* Flag for JMS monitoring of the cache */
+ private boolean m_jmsMonitoring;
+ /* Useful for log messages */
+ private StringBuffer m_buffer = new StringBuffer();
+ /* JMS log members */
+ private TopicConnection m_jmsConnection;
+ private Topic m_jmsTopic;
+ private TopicSession m_jmsSession;
+ private TopicPublisher m_jmsPublisher;
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
+ // Monitorable implementation ------------------------------------
+ public void sample(Object s)
+ {
+ synchronized (getCacheLock())
+ {
+ BeanCacheSnapshot snapshot = (BeanCacheSnapshot)s;
+ snapshot.m_passivatingBeans =
m_passivationHelper.m_passivationJobs.size();
+ CachePolicy policy = getCache();
+ if (policy instanceof Monitorable)
+ {
+ ((Monitorable)policy).sample(s);
+ }
+ }
+ }
+
// Public --------------------------------------------------------
+ public void setJMSMonitoringEnabled(boolean enable) {m_jmsMonitoring = enable;}
+ public boolean isJMSMonitoringEnabled() {return m_jmsMonitoring;}
+
+ public void sendMessage(Message message)
+ {
+ try
+ {
+ message.setJMSExpiration(5000);
+ message.setLongProperty("TIME", System.currentTimeMillis());
+ m_jmsPublisher.publish(m_jmsTopic, message);
+ }
+ catch (JMSException x)
+ {
+ Logger.exception(x);
+ }
+ }
+ public Message createMessage(Object id)
+ {
+ Message message = null;
+ try
+ {
+ message = m_jmsSession.createMessage();
+ message.setStringProperty("APPLICATION",
getContainer().getApplication().getName());
+ message.setStringProperty("BEAN",
getContainer().getBeanMetaData().getEjbName());
+ if (id != null)
+ {
+ message.setStringProperty("PRIMARY_KEY",
id.toString());
+ }
+ }
+ catch (JMSException x)
+ {
+ Logger.exception(x);
+ }
+ return message;
+ }
+
/* From InstanceCache interface */
public EnterpriseContext get(Object id)
throws RemoteException, NoSuchObjectException
@@ -86,10 +162,8 @@
ctx = acquireContext();
setKey(id, ctx);
activate(ctx);
+ logActivation(id);
insert(ctx);
-
- // Logger is very time expensive. Turn
on only for debug
- // Logger.debug("Activated bean " +
getContainer().getBeanMetaData().getEjbName() + " with id = " + id);
}
catch (Exception x)
{
@@ -246,12 +320,26 @@
String threadName = "Passivator Thread for " +
getContainer().getBeanMetaData().getEjbName();
ClassLoader cl = getContainer().getClassLoader();
m_passivator = new PassivatorQueue(threadName, cl);
+
+ // Setup JMS for cache monitoring
+ Context namingContext = new InitialContext();
+ Object factoryRef = namingContext.lookup("TopicConnectionFactory");
+ TopicConnectionFactory factory =
(TopicConnectionFactory)PortableRemoteObject.narrow(factoryRef,
TopicConnectionFactory.class);
+
+ m_jmsConnection = factory.createTopicConnection();
+
+ Object topicRef = namingContext.lookup("topic/beancache");
+ m_jmsTopic = (Topic)PortableRemoteObject.narrow(topicRef, Topic.class);
+ m_jmsSession = m_jmsConnection.createTopicSession(false,
Session.DUPS_OK_ACKNOWLEDGE);
+ m_jmsPublisher = m_jmsSession.createPublisher(m_jmsTopic);
}
/* From Service interface*/
public void start() throws Exception
{
getCache().start();
m_passivator.start();
+
+ m_jmsConnection.start();
}
/* From Service interface*/
public void stop()
@@ -262,11 +350,23 @@
getCache().stop();
}
m_passivator.stop();
+
+ try
+ {
+ m_jmsConnection.stop();
+ }
+ catch (JMSException ignored) {}
}
/* From Service interface*/
public void destroy()
{
getCache().destroy();
+
+ try
+ {
+ m_jmsConnection.close();
+ }
+ catch (JMSException ignored) {}
}
// Y overrides ---------------------------------------------------
@@ -281,6 +381,7 @@
protected void schedulePassivation(EnterpriseContext ctx)
{
m_passivationHelper.schedule(ctx);
+ logPassivationScheduled(getKey(ctx));
}
/**
* Tries to unschedule the given EnterpriseContext for passivation; returns
@@ -292,6 +393,118 @@
{
return m_passivationHelper.unschedule(id);
}
+
+ protected void logActivation(Object id)
+ {
+ m_buffer.setLength(0);
+ m_buffer.append("Activated bean ");
+ m_buffer.append(getContainer().getBeanMetaData().getEjbName());
+ m_buffer.append(" with id = ");
+ m_buffer.append(id);
+ Logger.debug(m_buffer.toString());
+
+ if (isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = createMessage(id);
+ try
+ {
+ message.setStringProperty("TYPE", "ACTIVATION");
+ }
+ catch (JMSException x)
+ {
+ Logger.exception(x);
+ }
+
+ // Send JMS Message
+ sendMessage(message);
+ }
+ }
+
+ protected void logPassivationScheduled(Object id)
+ {
+ m_buffer.setLength(0);
+ m_buffer.append("Scheduled passivation of bean ");
+ m_buffer.append(getContainer().getBeanMetaData().getEjbName());
+ m_buffer.append(" with id = ");
+ m_buffer.append(id);
+ Logger.debug(m_buffer.toString());
+
+ if (isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = createMessage(id);
+ try
+ {
+ message.setStringProperty("TYPE", "PASSIVATION");
+ message.setStringProperty("ACTIVITY", "SCHEDULED");
+ }
+ catch (JMSException x)
+ {
+ Logger.exception(x);
+ }
+
+ // Send JMS Message
+ sendMessage(message);
+ }
+ }
+
+ protected void logPassivation(Object id)
+ {
+ m_buffer.setLength(0);
+ m_buffer.append("Passivated bean ");
+ m_buffer.append(getContainer().getBeanMetaData().getEjbName());
+ m_buffer.append(" with id = ");
+ m_buffer.append(id);
+ Logger.debug(m_buffer.toString());
+
+ if (isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = createMessage(id);
+ try
+ {
+ message.setStringProperty("TYPE", "PASSIVATION");
+ message.setStringProperty("ACTIVITY", "PASSIVATED");
+ }
+ catch (JMSException x)
+ {
+ Logger.exception(x);
+ }
+
+ // Send JMS Message
+ sendMessage(message);
+ }
+ }
+
+ protected void logPassivationPostponed(Object id)
+ {
+ m_buffer.setLength(0);
+ m_buffer.append("Postponed passivation of bean ");
+ m_buffer.append(getContainer().getBeanMetaData().getEjbName());
+ m_buffer.append(" with id = ");
+ m_buffer.append(id);
+ Logger.debug(m_buffer.toString());
+
+ if (isJMSMonitoringEnabled())
+ {
+ // Prepare JMS message
+ Message message = createMessage(id);
+ try
+ {
+ message.setStringProperty("TYPE", "PASSIVATION");
+ message.setStringProperty("ACTIVITY", "POSTPONED");
+ }
+ catch (JMSException x)
+ {
+ Logger.exception(x);
+ }
+
+ // Send JMS Message
+ sendMessage(message);
+ }
+ }
+
/**
* Returns the container for this cache.
*/
@@ -364,8 +577,6 @@
// Create the passivation job
PassivationJob job = new PassivationJob(bean)
{
- private StringBuffer m_buffer = new
StringBuffer();
-
public void execute() throws Exception
{
EnterpriseContext ctx =
getEnterpriseContext();
@@ -423,8 +634,7 @@
getCache().insert(id, ctx);
}
- //
Logger is very time expensive.
-
log("Postponed passivation of bean ", id);
+
logPassivationPostponed(id);
return;
}
@@ -441,8 +651,7 @@
removeLock(id);
freeContext(ctx);
-
// Logger is very time expensive.
-
log("Passivated bean ", id);
+
logPassivation(id);
}
catch (RemoteException x)
{
@@ -461,15 +670,6 @@
{
mutex.release();
}
- }
- private void log(String msg, Object id)
- {
- m_buffer.setLength(0);
- m_buffer.append(msg);
-
m_buffer.append(getContainer().getBeanMetaData().getEjbName());
- m_buffer.append(" with id = ");
- m_buffer.append(id);
- Logger.debug(m_buffer.toString());
}
};