1 22 package org.jboss.cache.interceptors; 23 24 import org.jboss.cache.CacheListener; 25 import org.jboss.cache.CacheSPI; 26 import org.jboss.cache.Fqn; 27 import org.jboss.cache.marshall.MethodCall; 28 import org.jboss.cache.marshall.MethodDeclarations; 29 import org.jgroups.View; 30 31 import javax.management.ListenerNotFoundException ; 32 import javax.management.MBeanNotificationInfo ; 33 import javax.management.Notification ; 34 import javax.management.NotificationBroadcaster ; 35 import javax.management.NotificationBroadcasterSupport ; 36 import javax.management.NotificationFilter ; 37 import javax.management.NotificationListener ; 38 import java.util.HashMap ; 39 import java.util.Map ; 40 import java.util.concurrent.atomic.AtomicLong ; 41 42 48 public class CacheMgmtInterceptor extends Interceptor implements CacheMgmtInterceptorMBean, NotificationBroadcaster 49 { 50 public static final String 52 NOTIF_CACHE_STARTED = "org.jboss.cache.CacheStarted", 53 NOTIF_CACHE_STOPPED = "org.jboss.cache.CacheStopped", 54 NOTIF_NODE_CREATED = "org.jboss.cache.NodeCreated", 55 NOTIF_NODE_MODIFIED = "org.jboss.cache.NodeModified", 56 NOTIF_NODE_REMOVED = "org.jboss.cache.NodeRemoved", 57 NOTIF_NODE_MOVED = "org.jboss.cache.NodeMoved", 58 NOTIF_NODE_VISITED = "org.jboss.cache.NodeVisited", 59 NOTIF_NODE_EVICTED = "org.jboss.cache.NodeEvicted", 60 NOTIF_NODE_LOADED = "org.jboss.cache.NodeLoaded", 61 NOTIF_NODE_ACTIVATED = "org.jboss.cache.NodeActivated", 62 NOTIF_NODE_PASSIVATED = "org.jboss.cache.NodePassivated", 63 NOTIF_VIEW_CHANGED = "org.jboss.cache.ViewChanged"; 64 65 private static final String MSG_CACHE_STARTED = "Cache has been started."; 67 private static final String MSG_CACHE_STOPPED = "Cache has been stopped."; 68 private static final String MSG_NODE_CREATED = "Node has been created."; 69 private static final String MSG_NODE_MODIFIED = "Node has been modifed."; 70 private static final String MSG_NODE_REMOVED = "Node has been removed."; 71 private static final String MSG_NODE_MOVED = "Node has been moved."; 72 private static final String MSG_NODE_VISITED = "Node has been visited."; 73 private static final String MSG_NODE_EVICTED = "Node has been evicted."; 74 private static final String MSG_NODE_LOADED = "Node has been loaded."; 75 private static final String MSG_NODE_ACTIVATED = "Node has been activated."; 76 private static final String MSG_NODE_PASSIVATED = "Node has been passivated."; 77 private static final String MSG_VIEW_CHANGED = "Cache cluster view has changed."; 78 79 private static final String NOTIFICATION_NAME = Notification .class.getName(); 81 private static final String NOTIFICATION_DESCR = "JBossCache event notifications"; 82 83 private AtomicLong m_seq = new AtomicLong (0); 84 private int m_listeners = 0; 85 private long m_hit_times = 0; 86 private long m_miss_times = 0; 87 private long m_store_times = 0; 88 private long m_hits = 0; 89 private long m_misses = 0; 90 private long m_stores = 0; 91 private long m_evictions = 0; 92 private long m_start = System.currentTimeMillis(); 93 private long m_reset = m_start; 94 private CacheMgmtListener m_listener = new CacheMgmtListener(); 95 private NotificationBroadcasterSupport m_broadcaster = null; 96 97 public void setCache(CacheSPI cache) 98 { 99 super.setCache(cache); 100 m_broadcaster = new NotificationBroadcasterSupport (); 101 } 102 103 109 public Object invoke(MethodCall m) throws Throwable 110 { 111 Map attributes; 112 Object [] args = m.getArgs(); 113 Object retval; 114 115 if (!getStatisticsEnabled()) 117 return super.invoke(m); 118 119 long t1, t2; 120 switch (m.getMethodId()) 121 { 122 case MethodDeclarations.getKeyValueMethodLocal_id: 123 t1 = System.currentTimeMillis(); 126 retval = super.invoke(m); 127 t2 = System.currentTimeMillis(); 128 if (retval == null) 129 { 130 m_miss_times = m_miss_times + (t2 - t1); 131 m_misses++; 132 } 133 else 134 { 135 m_hit_times = m_hit_times + (t2 - t1); 136 m_hits++; 137 } 138 break; 139 case MethodDeclarations.putKeyValMethodLocal_id: 140 t1 = System.currentTimeMillis(); 141 retval = super.invoke(m); 142 t2 = System.currentTimeMillis(); 143 m_store_times = m_store_times + (t2 - t1); 144 m_stores++; 145 break; 146 case MethodDeclarations.putDataMethodLocal_id: 147 case MethodDeclarations.putDataEraseMethodLocal_id: 148 attributes = (Map ) args[2]; 150 t1 = System.currentTimeMillis(); 151 retval = super.invoke(m); 152 t2 = System.currentTimeMillis(); 153 154 if (attributes != null && attributes.size() > 0) 155 { 156 m_store_times = m_store_times + (t2 - t1); 157 m_stores = m_stores + attributes.size(); 158 } 159 break; 160 case MethodDeclarations.evictNodeMethodLocal_id: 161 case MethodDeclarations.evictVersionedNodeMethodLocal_id: 162 retval = super.invoke(m); 164 m_evictions++; 165 break; 166 default: 167 retval = super.invoke(m); 168 break; 169 } 170 171 return retval; 172 } 173 174 public long getHits() 175 { 176 return m_hits; 177 } 178 179 public long getMisses() 180 { 181 return m_misses; 182 } 183 184 public long getStores() 185 { 186 return m_stores; 187 } 188 189 public long getEvictions() 190 { 191 return m_evictions; 192 } 193 194 public double getHitMissRatio() 195 { 196 double total = m_hits + m_misses; 197 if (total == 0) 198 return 0; 199 return (m_hits / total); 200 } 201 202 public double getReadWriteRatio() 203 { 204 if (m_stores == 0) 205 return 0; 206 return (((double) (m_hits + m_misses) / (double) m_stores)); 207 } 208 209 public long getAverageReadTime() 210 { 211 long total = m_hits + m_misses; 212 if (total == 0) 213 return 0; 214 return (m_hit_times + m_miss_times) / total; 215 } 216 217 public long getAverageWriteTime() 218 { 219 if (m_stores == 0) 220 return 0; 221 return (m_store_times) / m_stores; 222 } 223 224 public int getNumberOfAttributes() 225 { 226 return cache.getNumberOfAttributes(); 227 } 228 229 public int getNumberOfNodes() 230 { 231 return cache.getNumberOfNodes(); 232 } 233 234 public long getElapsedTime() 235 { 236 return (System.currentTimeMillis() - m_start) / 1000; 237 } 238 239 public long getTimeSinceReset() 240 { 241 return (System.currentTimeMillis() - m_reset) / 1000; 242 } 243 244 public Map <String , Object > dumpStatistics() 245 { 246 Map <String , Object > retval = new HashMap <String , Object >(); 247 retval.put("Hits", m_hits); 248 retval.put("Misses", m_misses); 249 retval.put("Stores", m_stores); 250 retval.put("Evictions", m_evictions); 251 retval.put("NumberOfAttributes", cache.getNumberOfAttributes()); 252 retval.put("NumberOfNodes", cache.getNumberOfNodes()); 253 retval.put("ElapsedTime", getElapsedTime()); 254 retval.put("TimeSinceReset", getTimeSinceReset()); 255 retval.put("AverageReadTime", getAverageReadTime()); 256 retval.put("AverageWriteTime", getAverageWriteTime()); 257 retval.put("HitMissRatio", getHitMissRatio()); 258 retval.put("ReadWriteRatio", getReadWriteRatio()); 259 return retval; 260 } 261 262 public void resetStatistics() 263 { 264 m_hits = 0; 265 m_misses = 0; 266 m_stores = 0; 267 m_evictions = 0; 268 m_hit_times = 0; 269 m_miss_times = 0; 270 m_store_times = 0; 271 m_reset = System.currentTimeMillis(); 272 } 273 274 private synchronized void emitNotifications(boolean emit) 275 { 276 if (emit) 284 { 285 m_listeners++; 286 cache.addCacheListener(m_listener); 287 } 288 else 289 { 290 m_listeners--; 291 if (m_listeners <= 0) 292 { 293 cache.removeCacheListener(m_listener); 294 } 295 } 296 } 297 298 300 public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) 301 throws ListenerNotFoundException 302 { 303 m_broadcaster.removeNotificationListener(listener, filter, handback); 304 } 305 306 public MBeanNotificationInfo [] getNotificationInfo() 307 { 308 String [] types = new String [] 309 { 310 NOTIF_CACHE_STARTED, 311 NOTIF_CACHE_STOPPED, 312 NOTIF_NODE_CREATED, 313 NOTIF_NODE_EVICTED, 314 NOTIF_NODE_LOADED, 315 NOTIF_NODE_MODIFIED, 316 NOTIF_NODE_ACTIVATED, 317 NOTIF_NODE_PASSIVATED, 318 NOTIF_NODE_REMOVED, 319 NOTIF_NODE_VISITED, 320 NOTIF_VIEW_CHANGED 321 }; 322 323 MBeanNotificationInfo info = new MBeanNotificationInfo (types, NOTIFICATION_NAME, NOTIFICATION_DESCR); 324 return new MBeanNotificationInfo []{info}; 325 } 326 327 public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) 328 throws IllegalArgumentException 329 { 330 m_broadcaster.addNotificationListener(listener, filter, handback); 331 emitNotifications(true); 332 } 333 334 public void removeNotificationListener(NotificationListener listener) 335 throws ListenerNotFoundException 336 { 337 m_broadcaster.removeNotificationListener(listener); 338 emitNotifications(false); 339 } 340 341 private class CacheMgmtListener implements CacheListener 343 { 344 private long seq() 345 { 346 return m_seq.getAndIncrement(); 347 } 348 349 public void cacheStarted(CacheSPI cache) 350 { 351 Notification n = new Notification (NOTIF_CACHE_STARTED, this, seq(), MSG_CACHE_STARTED); 352 n.setUserData(cache.getConfiguration().getServiceName()); 353 m_broadcaster.sendNotification(n); 354 } 355 356 public void cacheStopped(CacheSPI cache) 357 { 358 Notification n = new Notification (NOTIF_CACHE_STOPPED, this, seq(), MSG_CACHE_STOPPED); 359 n.setUserData(cache.getConfiguration().getServiceName()); 360 m_broadcaster.sendNotification(n); 361 } 362 363 public void nodeCreated(Fqn fqn, boolean pre, boolean isLocal) 364 { 365 Notification n = new Notification (NOTIF_NODE_CREATED, this, seq(), MSG_NODE_CREATED); 366 n.setUserData(new Object []{fqn.toString(), pre, isLocal}); 367 m_broadcaster.sendNotification(n); 368 } 369 370 public void nodeEvicted(Fqn fqn, boolean pre, boolean isLocal) 371 { 372 Notification n = new Notification (NOTIF_NODE_EVICTED, this, seq(), MSG_NODE_EVICTED); 373 n.setUserData(new Object []{fqn.toString(), pre, isLocal}); 374 m_broadcaster.sendNotification(n); 375 } 376 377 public void nodeLoaded(Fqn fqn, boolean pre, Map data) 378 { 379 Notification n = new Notification (NOTIF_NODE_LOADED, this, seq(), MSG_NODE_LOADED); 380 n.setUserData(new Object []{fqn.toString(), pre}); 381 m_broadcaster.sendNotification(n); 382 } 383 384 public void nodeModified(Fqn fqn, boolean pre, boolean isLocal, ModificationType modType, Map data) 385 { 386 Notification n = new Notification (NOTIF_NODE_MODIFIED, this, seq(), MSG_NODE_MODIFIED); 387 n.setUserData(new Object []{fqn.toString(), pre, isLocal}); 388 m_broadcaster.sendNotification(n); 389 390 } 391 392 public void nodeRemoved(Fqn fqn, boolean pre, boolean isLocal, Map data) 393 { 394 Notification n = new Notification (NOTIF_NODE_REMOVED, this, seq(), MSG_NODE_REMOVED); 395 n.setUserData(new Object []{fqn.toString(), pre, isLocal}); 396 m_broadcaster.sendNotification(n); 397 } 398 399 public void nodeMoved(Fqn from, Fqn to, boolean pre, boolean isLocal) 400 { 401 Notification n = new Notification (NOTIF_NODE_MOVED, this, seq(), MSG_NODE_MOVED); 402 n.setUserData(new Object []{from.toString(), to.toString(), pre}); 403 m_broadcaster.sendNotification(n); 404 } 405 406 public void nodeVisited(Fqn fqn, boolean pre) 407 { 408 Notification n = new Notification (NOTIF_NODE_VISITED, this, seq(), MSG_NODE_VISITED); 409 n.setUserData(new Object []{fqn.toString(), pre}); 410 m_broadcaster.sendNotification(n); 411 } 412 413 public void viewChange(View view) 414 { 415 Notification n = new Notification (NOTIF_VIEW_CHANGED, this, seq(), MSG_VIEW_CHANGED); 416 n.setUserData(view.toString()); 417 m_broadcaster.sendNotification(n); 418 } 419 420 public void nodeActivated(Fqn fqn, boolean pre) 421 { 422 Notification n = new Notification (NOTIF_NODE_ACTIVATED, this, seq(), MSG_NODE_ACTIVATED); 423 n.setUserData(new Object []{fqn.toString(), pre}); 424 m_broadcaster.sendNotification(n); 425 } 426 427 public void nodePassivated(Fqn fqn, boolean pre) 428 { 429 Notification n = new Notification (NOTIF_NODE_PASSIVATED, this, seq(), MSG_NODE_PASSIVATED); 430 n.setUserData(new Object []{fqn.toString(), pre}); 431 m_broadcaster.sendNotification(n); 432 } 433 } 434 } 435 436 | Popular Tags |