001 package org.shiftone.jrat.provider.tree;
002
003
004 import org.shiftone.jrat.core.MethodKey;
005 import org.shiftone.jrat.core.spi.AbstractMethodHandlerFactory;
006 import org.shiftone.jrat.core.spi.MethodHandler;
007 import org.shiftone.jrat.core.spi.RuntimeContext;
008 import org.shiftone.jrat.provider.tree.command.DumpOutputCommandlet;
009 import org.shiftone.jrat.provider.tree.command.ResetCommandlet;
010 import org.shiftone.jrat.provider.tree.command.WriteOutputCommandlet;
011 import org.shiftone.jrat.provider.tree.ui.TraceViewBuilder;
012 import org.shiftone.jrat.util.AtomicLong;
013 import org.shiftone.jrat.util.log.Logger;
014
015 import java.util.HashSet;
016 import java.util.Set;
017
018
019 /**
020 * Class TreeMethodHandlerFactory
021 *
022 * @author jeff@shiftone.org (Jeff Drost)
023 */
024 public class TreeMethodHandlerFactory extends AbstractMethodHandlerFactory implements TreeMethodHandlerFactoryMBean {
025
026 private static final Logger LOG = Logger.getLogger(TreeMethodHandlerFactory.class);
027 private final TreeNode rootNode = new TreeNode();
028 private final Set allMethodKeys = new HashSet();
029 private final DelegateThreadLocal delegateThreadLocal = new DelegateThreadLocal(this);
030 private final AtomicLong methodHandlerCount = new AtomicLong();
031
032 public void startup(RuntimeContext context) throws Exception {
033 super.startup(context);
034 context.registerMBean(this);
035 context.register(new ResetCommandlet(this));
036 context.register(new WriteOutputCommandlet(this));
037 context.register(new DumpOutputCommandlet(this));
038 }
039
040
041 public synchronized final MethodHandler createMethodHandler(MethodKey methodKey) {
042
043
044 methodHandlerCount.incrementAndGet();
045 allMethodKeys.add(methodKey);
046
047 return new TreeMethodHandler(this, methodKey);
048 }
049
050
051 public long getMethodHandlerCount() {
052 return methodHandlerCount.get();
053 }
054
055
056 /**
057 * Returns the current thread's delegate instance. This delegate will
058 * operate on this factory's call tree data structure when events are
059 * processed.
060 */
061 public final Delegate getDelegate() {
062 return (Delegate) delegateThreadLocal.get();
063 }
064
065
066 public final TreeNode getRootNode() {
067 return rootNode;
068 }
069
070
071 public synchronized void writeOutputFile() {
072 writeOutputFile(getOutputFile());
073 }
074
075 public synchronized void reset() {
076 rootNode.reset();
077 }
078
079 public synchronized void writeOutputFile(String fileName) {
080
081 LOG.info("writeOutputFile...");
082
083 getContext().writeSerializable(fileName,
084 new TraceViewBuilder(
085 rootNode,
086 new HashSet(allMethodKeys), // copy to avoid sync issues
087 getContext().getStartTimeMs(),
088 System.currentTimeMillis(),
089 getContext().getSystemPropertiesAtStartup(),
090 getContext().getHostName(),
091 getContext().getHostAddress()
092 )
093 );
094
095 }
096
097
098 public synchronized void shutdown() {
099
100 LOG.info("shutdown...");
101 writeOutputFile();
102 LOG.info("shutdown complete");
103 }
104
105
106 public String toString() {
107 return "Tree Handler Factory";
108 }
109 }