1 22 package org.jboss.ejb.plugins; 23 24 import java.lang.reflect.Method ; 25 import java.security.Principal ; 26 import java.util.ArrayList ; 27 import java.util.List ; 28 29 import javax.jms.DeliveryMode ; 30 import javax.jms.JMSException ; 31 import javax.jms.Message ; 32 import javax.jms.Session ; 33 import javax.jms.Topic ; 34 import javax.jms.TopicConnection ; 35 import javax.jms.TopicConnectionFactory ; 36 import javax.jms.TopicPublisher ; 37 import javax.jms.TopicSession ; 38 import javax.naming.Context ; 39 import javax.naming.InitialContext ; 40 import javax.naming.NamingException ; 41 import javax.transaction.Transaction ; 42 43 import org.jboss.ejb.Container; 44 import org.jboss.invocation.Invocation; 45 import org.jboss.monitor.MetricsConstants; 46 47 57 public class MetricsInterceptor extends AbstractInterceptor 58 implements MetricsConstants 59 { 60 62 64 65 private String applicationName = "<undefined>"; 66 67 68 private String beanName = "<undefined>"; 69 70 71 private Thread publisher = null; 72 73 80 private List msgQueue = new ArrayList (2000); 81 82 83 90 public void setContainer(Container container) 91 { 92 super.setContainer(container); 93 if (container != null) 94 { 95 applicationName = container.getEjbModule().getName(); 96 beanName = container.getBeanMetaData().getJndiName(); 97 } 98 } 99 100 102 public Object invokeHome(Invocation mi) throws Exception 103 { 104 105 long begin = System.currentTimeMillis(); 106 107 try 108 { 109 return super.invokeHome(mi); 110 } 111 finally 112 { 113 if (mi.getMethod() != null && publisher.isAlive()) 114 { 115 addEntry(mi, begin, System.currentTimeMillis()); 116 } 117 } 118 } 119 120 public Object invoke(Invocation mi) throws Exception 121 { 122 123 long begin = System.currentTimeMillis(); 124 125 try 126 { 127 return super.invoke(mi); 128 } 129 finally 130 { 131 if (mi.getMethod() != null && publisher.isAlive()) 132 { 133 addEntry(mi, begin, System.currentTimeMillis()); 134 } 135 } 136 } 137 138 141 public void create() 142 { 143 log.warn("\n" + 144 "----------------------------------------------------------------------\n" + 145 "Deprecated MetricsInterceptor activated for bean: '" + beanName + "'\n" + 146 "Invocation metrics will be published in JMS Topic: 'topic/metrics'\n" + 147 "----------------------------------------------------------------------" 148 ); 149 150 publisher = new Thread (new Publisher ()); 153 publisher.setName("Metrics Publisher Thread for " + beanName); 154 publisher.setDaemon(true); 155 publisher.start(); 156 } 157 158 161 public void destroy() 162 { 163 publisher.interrupt(); 164 } 165 166 168 175 private final void addEntry(Invocation mi, long begin, long end) 176 { 177 178 179 180 Transaction tx = mi.getTransaction(); 181 Principal princ = mi.getPrincipal(); 182 Method method = mi.getMethod(); 183 Entry start = new Entry(princ, method, tx, begin, "START"); 184 Entry stop = new Entry(princ, method, tx, end, "STOP"); 185 186 synchronized (msgQueue) 189 { 190 191 msgQueue.add(start); 194 msgQueue.add(stop); 195 } 196 } 197 198 private Message createMessage(Session session, String principal, int txID, 199 String method, String checkpoint, long time) 200 { 201 202 try 203 { 204 Message msg = session.createMessage(); 205 206 msg.setJMSType(INVOCATION_METRICS); 207 msg.setStringProperty(CHECKPOINT, checkpoint); 208 msg.setStringProperty(BEAN, beanName); 209 msg.setObjectProperty(METHOD, method); 210 msg.setLongProperty(TIME, time); 211 212 if (txID != -1) 213 msg.setStringProperty("ID", String.valueOf(txID)); 214 215 if (principal != null) 216 msg.setStringProperty("PRINCIPAL", principal); 217 218 return msg; 219 } 220 catch (Exception e) 221 { 222 return null; 225 } 226 } 227 228 231 private class Publisher implements Runnable 232 { 233 234 235 private boolean running = true; 236 237 private int delay = 2000; 238 239 private TopicConnection connection = null; 240 241 256 public void run() 257 { 258 259 try 260 { 261 final boolean IS_TRANSACTED = true; 262 final int ACKNOWLEDGE_MODE = Session.DUPS_OK_ACKNOWLEDGE; 263 264 Context namingContext = new InitialContext (); 266 TopicConnectionFactory fact = (TopicConnectionFactory ) namingContext.lookup("java:/ConnectionFactory"); 267 268 connection = fact.createTopicConnection(); 269 270 Topic topic = (Topic ) namingContext.lookup("topic/metrics"); 271 TopicSession session = connection.createTopicSession(IS_TRANSACTED, ACKNOWLEDGE_MODE); 272 TopicPublisher pub = session.createPublisher(topic); 273 274 pub.setDeliveryMode(DeliveryMode.NON_PERSISTENT); 275 pub.setPriority(Message.DEFAULT_PRIORITY); 276 pub.setTimeToLive(Message.DEFAULT_TIME_TO_LIVE); 277 278 connection.start(); 280 281 while (running) 283 { 284 285 Object [] array; 286 long sleepTime = delay; 287 288 try 289 { 290 Thread.sleep(sleepTime); 291 292 long begin = System.currentTimeMillis(); 295 296 synchronized (msgQueue) 299 { 300 array = msgQueue.toArray(); 301 msgQueue.clear(); 302 } 303 304 for (int i = 0; i < array.length; ++i) 306 { 307 Message msg = createMessage(session, 308 ((Entry) array[i]).principal, 309 ((Entry) array[i]).id, 310 ((Entry) array[i]).method, 311 ((Entry) array[i]).checkpoint, 312 ((Entry) array[i]).time 313 ); 314 315 pub.publish(msg); 316 } 317 318 try 322 { 323 session.commit(); 324 } 325 catch (Exception e) 326 { 327 } 328 329 long end = System.currentTimeMillis(); 332 333 sleepTime = delay - (end - begin); 334 } 335 catch (InterruptedException e) 336 { 337 running = false; 339 } 340 } 341 } 342 catch (NamingException e) 343 { 344 log.warn(Thread.currentThread().getName() + " exiting", e); 345 } 346 catch (JMSException e) 347 { 348 log.warn(Thread.currentThread().getName() + " exiting", e); 349 } 350 finally 351 { 352 synchronized (msgQueue) 354 { 355 msgQueue.clear(); 356 } 357 358 try 359 { 360 if (connection != null) 361 connection.close(); 362 } 363 catch (JMSException e) 364 { 365 log.warn(e); 366 } 367 } 368 } 369 } 370 371 376 private final class Entry 377 { 378 int id = -1; 379 long time; 380 String principal = null; 381 String checkpoint; 382 String method; 383 384 Entry(Principal principal, Method method, Transaction tx, long time, String checkpoint) 385 { 386 this.time = time; 387 this.checkpoint = checkpoint; 388 this.method = method.getName(); 389 390 if (tx != null) 391 this.id = tx.hashCode(); 392 if (principal != null) 393 this.principal = principal.getName(); 394 } 395 } 396 } 397 | Popular Tags |