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 }