mirror of https://github.com/mchr3k/org.intrace
Add support for capturing callers trace
This commit is contained in:
parent
d180ca0814
commit
a2a92d3814
|
|
@ -49,9 +49,8 @@
|
|||
<manifest>
|
||||
<attribute name="Main-Class" value="org.intrace.client.cui.TraceClient" />
|
||||
<attribute name="Class-Path" value="." />
|
||||
</manifest>
|
||||
<fileset dir="./bin" includes="**/output/trace/TraceConfigConstants.class" />
|
||||
<fileset dir="./bin" includes="**/agent/AgentConfigConstants.class" />
|
||||
</manifest>
|
||||
<fileset dir="./bin" includes="**/shared/*.class" />
|
||||
<fileset dir="./bin" includes="**/client/cui/TraceClient.class" />
|
||||
</jar>
|
||||
|
||||
|
|
@ -61,8 +60,7 @@
|
|||
<attribute name="Main-Class" value="org.intrace.client.gui.TraceClient" />
|
||||
<attribute name="Class-Path" value="." />
|
||||
</manifest>
|
||||
<fileset dir="./bin" includes="**/output/trace/TraceSettingsConstants.class" />
|
||||
<fileset dir="./bin" includes="**/agent/AgentConfigConstants.class" />
|
||||
<fileset dir="./bin" includes="**/shared/*.class" />
|
||||
<fileset dir="./bin" includes="**/client/gui/**/*.class" />
|
||||
<zipfileset excludes="META-INF/*.SF" src="lib/org.eclipse.swt.win32.win32.x86_3.5.2.v3557f.jar" />
|
||||
</jar>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ import java.io.IOException;
|
|||
import java.lang.instrument.Instrumentation;
|
||||
|
||||
import org.intrace.agent.server.AgentServer;
|
||||
import org.intrace.output.AgentHelper;
|
||||
import org.intrace.output.callers.CallersOutput;
|
||||
import org.intrace.output.trace.TraceOutput;
|
||||
|
||||
/**
|
||||
* Trace Agent: Installs a Class Transformer to add trace lines.
|
||||
|
|
@ -43,8 +46,13 @@ public class Agent
|
|||
{
|
||||
System.out.println("Loaded Tracing Agent.");
|
||||
|
||||
if (agentArgs == null) agentArgs = "";
|
||||
|
||||
AgentHelper.outputHandlers.put(new TraceOutput(), new Object());
|
||||
AgentHelper.outputHandlers.put(new CallersOutput(), new Object());
|
||||
|
||||
AgentSettings args = new AgentSettings(agentArgs);
|
||||
AgentHelper.getActiveOutputHandler().getResponse(agentArgs);
|
||||
AgentHelper.getResponses(agentArgs);
|
||||
|
||||
ClassTransformer t = new ClassTransformer(inst, args);
|
||||
inst.addTransformer(t, true);
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
package org.intrace.agent;
|
||||
|
||||
import org.intrace.output.IOutput;
|
||||
import org.intrace.output.trace.TraceOutput;
|
||||
|
||||
|
||||
/**
|
||||
* Static implementation of the TraceWriter interface
|
||||
*/
|
||||
public class AgentHelper
|
||||
{
|
||||
private static IOutput outputHandler = new TraceOutput();
|
||||
|
||||
public static IOutput getActiveOutputHandler()
|
||||
{
|
||||
return outputHandler;
|
||||
}
|
||||
|
||||
public static void enter(String className, String methodName)
|
||||
{
|
||||
outputHandler.enter(className, methodName);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, byte byteArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, byteArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, byte[] byteArrayArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, byteArrayArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, short shortArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, shortArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, short[] shortArrayArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, shortArrayArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, int intArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, intArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, int[] intArrayArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, intArrayArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, long longArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, longArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, long[] longArrayArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, longArrayArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, float floatArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, floatArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, float[] floatArrayArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, floatArrayArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, double doubleArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, doubleArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, double[] doubleArrayArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, doubleArrayArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, boolean boolArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, boolArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, boolean[] boolArrayArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, boolArrayArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, char charArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, charArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, char[] charArrayArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, charArrayArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, Object objArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, objArg);
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, Object[] objArrayArg)
|
||||
{
|
||||
outputHandler.arg(className, methodName, objArrayArg);
|
||||
}
|
||||
|
||||
public static void branch(String className, String methodName, int lineNo)
|
||||
{
|
||||
outputHandler.branch(className, methodName, lineNo);
|
||||
}
|
||||
|
||||
public static void exit(String className, String methodName, int lineNo)
|
||||
{
|
||||
outputHandler.exit(className, methodName, lineNo);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,26 +4,28 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.intrace.shared.AgentConfigConstants;
|
||||
|
||||
/**
|
||||
* Args Format:
|
||||
* "[arg1[arg2[arg3"
|
||||
*
|
||||
*
|
||||
* where argx is of the form
|
||||
* value-parameter
|
||||
*/
|
||||
public class AgentSettings
|
||||
{
|
||||
private Pattern classRegex = Pattern.compile("");
|
||||
private Pattern classRegex = Pattern.compile(".*");
|
||||
private boolean tracingEnabled = false;
|
||||
private boolean saveTracedClassfiles = false;
|
||||
private boolean verboseMode = false;
|
||||
private boolean allowJarsToBeTraced = false;
|
||||
|
||||
|
||||
public AgentSettings(String args)
|
||||
{
|
||||
parseArg(args);
|
||||
}
|
||||
|
||||
|
||||
public AgentSettings(AgentSettings oldInstance)
|
||||
{
|
||||
classRegex = oldInstance.getClassRegex();
|
||||
|
|
@ -38,41 +40,41 @@ public class AgentSettings
|
|||
String[] seperateArgs = args.split("\\[");
|
||||
for (int ii = 0; ii < seperateArgs.length; ii++)
|
||||
{
|
||||
parseArg(seperateArgs[ii].toLowerCase());
|
||||
parseArg(seperateArgs[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void parseArg(String arg)
|
||||
{
|
||||
if (arg.equals("verbose-true"))
|
||||
if (arg.toLowerCase().equals("verbose-true"))
|
||||
{
|
||||
verboseMode = true;
|
||||
}
|
||||
else if (arg.equals("verbose-false"))
|
||||
else if (arg.toLowerCase().equals("verbose-false"))
|
||||
{
|
||||
verboseMode = false;
|
||||
}
|
||||
else if (arg.equals("instru-true"))
|
||||
else if (arg.toLowerCase().equals("instru-true"))
|
||||
{
|
||||
tracingEnabled = true;
|
||||
}
|
||||
else if (arg.equals("instru-false"))
|
||||
else if (arg.toLowerCase().equals("instru-false"))
|
||||
{
|
||||
tracingEnabled = false;
|
||||
}
|
||||
else if (arg.equals("saveinstru-true"))
|
||||
else if (arg.toLowerCase().equals("saveinstru-true"))
|
||||
{
|
||||
saveTracedClassfiles = true;
|
||||
}
|
||||
else if (arg.equals("saveinstru-false"))
|
||||
else if (arg.toLowerCase().equals("saveinstru-false"))
|
||||
{
|
||||
saveTracedClassfiles = false;
|
||||
}
|
||||
else if (arg.equals("instrujars-true"))
|
||||
else if (arg.toLowerCase().equals("instrujars-true"))
|
||||
{
|
||||
allowJarsToBeTraced = true;
|
||||
}
|
||||
else if (arg.equals("instrujars-false"))
|
||||
else if (arg.toLowerCase().equals("instrujars-false"))
|
||||
{
|
||||
allowJarsToBeTraced = false;
|
||||
}
|
||||
|
|
@ -107,7 +109,7 @@ public class AgentSettings
|
|||
{
|
||||
return allowJarsToBeTraced;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
@ -118,10 +120,11 @@ public class AgentSettings
|
|||
currentSettings += "Trace Classes in JAR Files : " + allowJarsToBeTraced + "\n";
|
||||
return currentSettings;
|
||||
}
|
||||
|
||||
|
||||
public Map<String,String> getSettingsMap()
|
||||
{
|
||||
Map<String,String> settingsMap = new HashMap<String, String>();
|
||||
settingsMap.put(AgentConfigConstants.MAP_ID, AgentConfigConstants.MAP_ID);
|
||||
settingsMap.put(AgentConfigConstants.TRACING_ENABLED, Boolean.toString(tracingEnabled));
|
||||
settingsMap.put(AgentConfigConstants.CLASS_REGEX, classRegex.pattern());
|
||||
settingsMap.put(AgentConfigConstants.ALLOW_JARS_TO_BE_TRACED, Boolean.toString(allowJarsToBeTraced));
|
||||
|
|
|
|||
|
|
@ -9,10 +9,12 @@ import java.lang.instrument.Instrumentation;
|
|||
import java.lang.instrument.UnmodifiableClassException;
|
||||
import java.security.CodeSource;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
|
||||
import org.intrace.output.AgentHelper;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
|
||||
/**
|
||||
|
|
@ -24,9 +26,9 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
* Map of modified class names to their original bytes
|
||||
*/
|
||||
private final Set<String> modifiedClasses =
|
||||
new ConcurrentSkipListSet<String>();
|
||||
new ConcurrentSkipListSet<String>();
|
||||
private final Instrumentation inst;
|
||||
private final AgentSettings args;
|
||||
private final AgentSettings args;
|
||||
|
||||
/**
|
||||
* cTor
|
||||
|
|
@ -40,7 +42,7 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
public ClassTransformer(Instrumentation xiInst, AgentSettings xiArgs)
|
||||
{
|
||||
inst = xiInst;
|
||||
args = xiArgs;
|
||||
args = xiArgs;
|
||||
if (args.isVerboseMode())
|
||||
{
|
||||
System.out.println(args.toString());
|
||||
|
|
@ -94,7 +96,7 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
}
|
||||
}
|
||||
else if (args.isTracingEnabled() &&
|
||||
isToBeConsideredForCoverage(loadedClass.getName(), loadedClass.getProtectionDomain()))
|
||||
isToBeConsideredForCoverage(loadedClass.getName(), loadedClass.getProtectionDomain()))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -145,7 +147,7 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Don't modify a class which is already modified
|
||||
if (modifiedClasses.contains(className))
|
||||
{
|
||||
|
|
@ -181,9 +183,9 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
|
||||
// Don't modify a class from a JAR file unless this is allowed
|
||||
CodeSource codeSource = protectionDomain.getCodeSource();
|
||||
if (!args.allowJarsToBeTraced() &&
|
||||
(codeSource != null) &&
|
||||
codeSource.getLocation().getPath().endsWith(".jar"))
|
||||
if (!args.allowJarsToBeTraced() &&
|
||||
(codeSource != null) &&
|
||||
codeSource.getLocation().getPath().endsWith(".jar"))
|
||||
{
|
||||
if (args.isVerboseMode())
|
||||
{
|
||||
|
|
@ -191,7 +193,7 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -200,12 +202,12 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
Class<?> classBeingRedefined,
|
||||
ProtectionDomain protectionDomain,
|
||||
byte[] originalClassfile)
|
||||
throws IllegalClassFormatException
|
||||
throws IllegalClassFormatException
|
||||
{
|
||||
String className = internalClassName.replace('/', '.');
|
||||
if (args.isTracingEnabled() &&
|
||||
isToBeConsideredForCoverage(className, protectionDomain))
|
||||
{
|
||||
{
|
||||
if (args.isVerboseMode())
|
||||
{
|
||||
System.out.println("!! Instrumenting class: " + className);
|
||||
|
|
@ -233,7 +235,7 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
else
|
||||
{
|
||||
System.out.println("Can't create directory " + parentDir +
|
||||
" for saving traced classfiles.");
|
||||
" for saving traced classfiles.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
@ -241,7 +243,7 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
modifiedClasses.add(className);
|
||||
return newBytes;
|
||||
}
|
||||
|
|
@ -255,21 +257,21 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
private byte[] readAndModifyClassForTracing(String xiClassName,
|
||||
byte[] classfileBuffer)
|
||||
{
|
||||
ClassReader cr = new ClassReader(classfileBuffer);
|
||||
ClassBranchLineAnalysis analysis = new ClassBranchLineAnalysis();
|
||||
cr.accept(analysis, false);
|
||||
InstrumentedClassWriter writer = new InstrumentedClassWriter(xiClassName,
|
||||
cr,
|
||||
analysis.getMethodBranchLabels());
|
||||
cr.accept(writer, false);
|
||||
return writer.toByteArray();
|
||||
ClassReader cr = new ClassReader(classfileBuffer);
|
||||
ClassBranchLineAnalysis analysis = new ClassBranchLineAnalysis();
|
||||
cr.accept(analysis, false);
|
||||
InstrumentedClassWriter writer = new InstrumentedClassWriter(xiClassName,
|
||||
cr,
|
||||
analysis.getMethodBranchLabels());
|
||||
cr.accept(writer, false);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
public String getResponse(String message)
|
||||
public List<String> getResponse(String message)
|
||||
{
|
||||
AgentSettings oldSettings = new AgentSettings(args);
|
||||
args.parseArgs(message);
|
||||
|
||||
|
||||
if (args.isVerboseMode() &&
|
||||
(oldSettings.isVerboseMode() != args.isVerboseMode()))
|
||||
{
|
||||
|
|
@ -298,8 +300,8 @@ public class ClassTransformer implements ClassFileTransformer
|
|||
recheckModifiedClasses();
|
||||
traceLoadedClasses();
|
||||
}
|
||||
|
||||
return AgentHelper.getActiveOutputHandler().getResponse(message);
|
||||
|
||||
return AgentHelper.getResponses(message);
|
||||
}
|
||||
|
||||
public Map<String, String> getSettings()
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import org.objectweb.asm.Type;
|
|||
*/
|
||||
public class InstrumentedMethodWriter extends MethodAdapter
|
||||
{
|
||||
private static final String HELPER_CLASS = "org/intrace/agent/AgentHelper";
|
||||
private static final String HELPER_CLASS = "org/intrace/output/AgentHelper";
|
||||
private final String className;
|
||||
private final String methodName;
|
||||
private final String methodDescriptor;
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ import java.io.ObjectOutputStream;
|
|||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.intrace.agent.AgentHelper;
|
||||
import org.intrace.agent.ClassTransformer;
|
||||
import org.intrace.output.AgentHelper;
|
||||
|
||||
/**
|
||||
* Server thread handling a single connected client.
|
||||
|
|
@ -24,11 +25,11 @@ public class AgentClientConnection implements Runnable
|
|||
|
||||
/**
|
||||
* cTor
|
||||
* @param agentServer
|
||||
* @param agentServer
|
||||
* @param xiConnectedClient
|
||||
* @param xiTransformer
|
||||
*/
|
||||
public AgentClientConnection(AgentServer agentServer,
|
||||
public AgentClientConnection(AgentServer agentServer,
|
||||
Socket xiConnectedClient,
|
||||
ClassTransformer xiTransformer)
|
||||
{
|
||||
|
|
@ -42,50 +43,53 @@ public class AgentClientConnection implements Runnable
|
|||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
try
|
||||
{
|
||||
boolean quit = false;
|
||||
while (!quit)
|
||||
{
|
||||
boolean quit = false;
|
||||
while (!quit)
|
||||
try
|
||||
{
|
||||
try
|
||||
String message = receiveMessage();
|
||||
if (message.equals("getsettings"))
|
||||
{
|
||||
String message = receiveMessage();
|
||||
if (message.equals("getsettings"))
|
||||
Map<String,String> settingsMap = new HashMap<String, String>();
|
||||
settingsMap.putAll(transformer.getSettings());
|
||||
settingsMap.putAll(AgentHelper.getSettings());
|
||||
serverRef.broadcastMessage(this, settingsMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<String> responses = transformer.getResponse(message);
|
||||
if (responses.size() > 0)
|
||||
{
|
||||
Map<String,String> settingsMap = new HashMap<String, String>();
|
||||
settingsMap.putAll(transformer.getSettings());
|
||||
settingsMap.putAll(AgentHelper.getActiveOutputHandler().getSettingsMap());
|
||||
serverRef.broadcastMessage(this, settingsMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
String response = transformer.getResponse(message);
|
||||
if (response != null)
|
||||
for (String response : responses)
|
||||
{
|
||||
sendMessage(response);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendMessage("OK");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendMessage("OK");
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
quit = true;
|
||||
}
|
||||
}
|
||||
System.out.println("Disconnected from: " + connectedClient.getPort());
|
||||
connectedClient.close();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
serverRef.removeClientConnection(this);
|
||||
catch (IOException e)
|
||||
{
|
||||
quit = true;
|
||||
}
|
||||
}
|
||||
System.out.println("Disconnected from: " + connectedClient.getPort());
|
||||
connectedClient.close();
|
||||
}
|
||||
catch (IOException e1)
|
||||
{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
serverRef.removeClientConnection(this);
|
||||
}
|
||||
}
|
||||
|
||||
private String receiveMessage() throws IOException
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
package org.intrace.client.gui;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
public class CallersRegexInputWindow
|
||||
{
|
||||
private Shell sShell = null; // @jve:decl-index=0:visual-constraint="10,10"
|
||||
private Text regexInput = null;
|
||||
private Button setRegexButton = null;
|
||||
private Button cancelButton = null;
|
||||
|
||||
private TraceWindow mainWindowRef = null; // @jve:decl-index=0:
|
||||
|
||||
/**
|
||||
* This method initializes sShell
|
||||
*/
|
||||
private void createSShell()
|
||||
{
|
||||
GridData gridData2 = new GridData();
|
||||
gridData2.widthHint = 100;
|
||||
gridData2.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER;
|
||||
GridData gridData1 = new GridData();
|
||||
gridData1.widthHint = 100;
|
||||
gridData1.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER;
|
||||
GridData gridData = new GridData();
|
||||
gridData.horizontalSpan = 2;
|
||||
gridData.widthHint = 300;
|
||||
GridLayout gridLayout = new GridLayout();
|
||||
gridLayout.numColumns = 2;
|
||||
gridLayout.makeColumnsEqualWidth = true;
|
||||
sShell = new Shell(SWT.APPLICATION_MODAL | SWT.CLOSE | SWT.TITLE | SWT.MIN);
|
||||
sShell.setText("Enter Method Regex");
|
||||
sShell.setLayout(gridLayout);
|
||||
sShell.setSize(new Point(326, 82));
|
||||
sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter()
|
||||
{
|
||||
@Override
|
||||
public void shellClosed(org.eclipse.swt.events.ShellEvent e)
|
||||
{
|
||||
sShell.dispose();
|
||||
}
|
||||
});
|
||||
regexInput = new Text(sShell, SWT.BORDER);
|
||||
regexInput.setLayoutData(gridData);
|
||||
setRegexButton = new Button(sShell, SWT.NONE);
|
||||
setRegexButton.setText("Set Method Regex");
|
||||
setRegexButton.setLayoutData(gridData1);
|
||||
setRegexButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
mainWindowRef.setCallersRegex(regexInput.getText());
|
||||
sShell.close();
|
||||
}
|
||||
});
|
||||
cancelButton = new Button(sShell, SWT.NONE);
|
||||
cancelButton.setText("Cancel");
|
||||
cancelButton.setLayoutData(gridData2);
|
||||
cancelButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
sShell.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void open(TraceWindow instanceWindowRef, String initText)
|
||||
{
|
||||
createSShell();
|
||||
sShell.open();
|
||||
regexInput.setText(initText);
|
||||
mainWindowRef = instanceWindowRef;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,16 +11,21 @@ public class ClientStrings
|
|||
public static final String DISABLE_SAVECLASSES = "Don't Save Classes";
|
||||
public static final String ENABLE_VERBOSEMODE = "Enable Verbose Mode";
|
||||
public static final String DISABLE_VERBOSEMODE = "Disable Verbose Mode";
|
||||
|
||||
public static final String ENABLE_EE_TRACE = "Enable Entry/Exit Trace";
|
||||
public static final String DISABLE_EE_TRACE = "Disable Entry/Exit Trace";
|
||||
public static final String ENABLE_BRANCH_TRACE = "Enable Branch Trace";
|
||||
public static final String DISABLE_BRANCH_TRACE = "Disable Branch Trace";
|
||||
public static final String ENABLE_ARGS_TRACE = "Enable Args Trace";
|
||||
public static final String DISABLE_ARGS_TRACE = "Disable Args Trace";
|
||||
public static final String ENABLE_STDOUT_TRACE = "Enable StdOut Trace";
|
||||
public static final String DISABLE_STDOUT_TRACE = "Disable StdOut Trace";
|
||||
public static final String ENABLE_FILE_TRACE = "Enable File Trace";
|
||||
public static final String DISABLE_FILE_TRACE = "Disable File Trace";
|
||||
public static final String ENABLE_NETWORK_TRACE = "Enable Network Trace";
|
||||
public static final String DISABLE_NETWORK_TRACE = "Disable Network Trace";
|
||||
|
||||
public static final String BEGIN_CAPTURE_CALLERS = "Begin Callers Capture";
|
||||
public static final String END_CAPTURE_CALLERS = "End Callers Capture";
|
||||
|
||||
public static final String ENABLE_STDOUT_OUTPUT = "Enable StdOut Output";
|
||||
public static final String DISABLE_STDOUT_OUTPUT = "Disable StdOut Output";
|
||||
public static final String ENABLE_FILE_OUTPUT = "Enable File Output";
|
||||
public static final String DISABLE_FILE_OUTPUT = "Disable File Output";
|
||||
public static final String ENABLE_NETWORK_OUTPUT = "Enable Network Output";
|
||||
public static final String DISABLE_NETWORK_OUTPUT = "Disable Network Output";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
package org.intrace.client.gui;
|
||||
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
public class InstruRegexInputWindow
|
||||
{
|
||||
private Shell sShell = null; // @jve:decl-index=0:visual-constraint="10,10"
|
||||
private Text regexInput = null;
|
||||
private Button setRegexButton = null;
|
||||
private Button cancelButton = null;
|
||||
|
||||
private TraceWindow mainWindowRef = null; // @jve:decl-index=0:
|
||||
|
||||
/**
|
||||
* This method initializes sShell
|
||||
*/
|
||||
private void createSShell()
|
||||
{
|
||||
GridData gridData2 = new GridData();
|
||||
gridData2.widthHint = 100;
|
||||
gridData2.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER;
|
||||
GridData gridData1 = new GridData();
|
||||
gridData1.widthHint = 100;
|
||||
gridData1.horizontalAlignment = org.eclipse.swt.layout.GridData.CENTER;
|
||||
GridData gridData = new GridData();
|
||||
gridData.horizontalSpan = 2;
|
||||
gridData.widthHint = 300;
|
||||
GridLayout gridLayout = new GridLayout();
|
||||
gridLayout.numColumns = 2;
|
||||
gridLayout.makeColumnsEqualWidth = true;
|
||||
sShell = new Shell(SWT.APPLICATION_MODAL | SWT.CLOSE | SWT.TITLE | SWT.MIN);
|
||||
sShell.setText("Enter Regex");
|
||||
sShell.setLayout(gridLayout);
|
||||
sShell.setSize(new Point(326, 82));
|
||||
sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter()
|
||||
{
|
||||
@Override
|
||||
public void shellClosed(org.eclipse.swt.events.ShellEvent e)
|
||||
{
|
||||
sShell.dispose();
|
||||
}
|
||||
});
|
||||
regexInput = new Text(sShell, SWT.BORDER);
|
||||
regexInput.setLayoutData(gridData);
|
||||
setRegexButton = new Button(sShell, SWT.NONE);
|
||||
setRegexButton.setText("Set Class Regex");
|
||||
setRegexButton.setLayoutData(gridData1);
|
||||
setRegexButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
mainWindowRef.setRegex(regexInput.getText());
|
||||
sShell.close();
|
||||
}
|
||||
});
|
||||
cancelButton = new Button(sShell, SWT.NONE);
|
||||
cancelButton.setText("Cancel");
|
||||
cancelButton.setLayoutData(gridData2);
|
||||
cancelButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
sShell.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void open(TraceWindow instanceWindowRef, String initText)
|
||||
{
|
||||
createSShell();
|
||||
sShell.open();
|
||||
regexInput.setText(initText);
|
||||
mainWindowRef = instanceWindowRef;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import java.net.InetAddress;
|
|||
import java.net.Socket;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
|
|
@ -17,33 +18,38 @@ import org.eclipse.swt.widgets.Composite;
|
|||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.TabFolder;
|
||||
import org.eclipse.swt.widgets.TabItem;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
import org.eclipse.swt.widgets.Tree;
|
||||
import org.eclipse.swt.widgets.TreeItem;
|
||||
import org.intrace.client.gui.helper.ControlConnectionThread;
|
||||
import org.intrace.client.gui.helper.NetworkTraceReceiverThread;
|
||||
import org.intrace.client.gui.helper.NetworkDataReceiverThread;
|
||||
import org.intrace.client.gui.helper.ParsedSettingsData;
|
||||
import org.intrace.shared.CallersConfigConstants;
|
||||
|
||||
public class TraceWindow
|
||||
{
|
||||
{
|
||||
// Window refs
|
||||
private TraceWindow traceDialogRef = this;
|
||||
private NewConnectionWindow newConnectionDialogRef;
|
||||
|
||||
private final TraceWindow traceDialogRef = this;
|
||||
private final NewConnectionWindow newConnectionDialogRef;
|
||||
|
||||
// Network details
|
||||
private InetAddress remoteAddress;
|
||||
private final InetAddress remoteAddress;
|
||||
private boolean networkTraceEnabled = false;
|
||||
|
||||
|
||||
// Threads
|
||||
private NetworkTraceReceiverThread networkTraceThread;
|
||||
private final ControlConnectionThread controlThread;
|
||||
|
||||
private NetworkDataReceiverThread networkTraceThread;
|
||||
private final ControlConnectionThread controlThread;
|
||||
|
||||
// Settings
|
||||
private ParsedSettingsData settingsData = new ParsedSettingsData(new HashMap<String, String>()); // @jve:decl-index=0:
|
||||
|
||||
|
||||
// UI Elements
|
||||
private Shell sShell = null;
|
||||
private Button toggleEntryExitButton = null;
|
||||
private Button disconnectButton = null;
|
||||
private Text statusTextArea = null;
|
||||
private Text statusTextArea = null;
|
||||
private Button toggleStdOutButton = null;
|
||||
private Button toggleBranchButton = null;
|
||||
private Button toggleArgsButton = null;
|
||||
|
|
@ -59,13 +65,19 @@ public class TraceWindow
|
|||
private Button toggleVerboseMode = null;
|
||||
private Button toggleFileOutputButton = null;
|
||||
private Button toggleNetworkTraceButton = null;
|
||||
|
||||
private TabFolder outputTabFolder = null;
|
||||
private TabItem textOutputTabItem = null;
|
||||
private TabItem callersOutputTabItem = null;
|
||||
private Tree callersTree = null;
|
||||
private Label callersLabel = null;
|
||||
private Button callersStateButton = null;
|
||||
|
||||
public TraceWindow(NewConnectionWindow instanceRef, Socket socket)
|
||||
{
|
||||
this.newConnectionDialogRef = instanceRef;
|
||||
this.remoteAddress = socket.getInetAddress();
|
||||
controlThread = new ControlConnectionThread(socket, this);
|
||||
controlThread.start();
|
||||
controlThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,6 +85,8 @@ public class TraceWindow
|
|||
*/
|
||||
private void createSShell()
|
||||
{
|
||||
GridData gridData12 = new GridData();
|
||||
gridData12.widthHint = 150;
|
||||
GridData gridData22 = new GridData();
|
||||
gridData22.widthHint = 150;
|
||||
GridData gridData11 = new GridData();
|
||||
|
|
@ -111,21 +125,23 @@ public class TraceWindow
|
|||
toggleInstrumentEnabled.setText(ClientStrings.ENABLE_INSTR);
|
||||
toggleInstrumentEnabled.setLayoutData(gridData31);
|
||||
toggleInstrumentEnabled
|
||||
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.instrEnabled, "[instru-true", "[instru-false");
|
||||
}
|
||||
});
|
||||
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.instrEnabled, "[instru-true", "[instru-false");
|
||||
}
|
||||
});
|
||||
setClassRegexButton = new Button(sShell, SWT.LEFT);
|
||||
setClassRegexButton.setText(ClientStrings.SET_CLASSREGEX);
|
||||
setClassRegexButton.setLayoutData(gridData41);
|
||||
setClassRegexButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
RegexInput regexInput = new RegexInput();
|
||||
InstruRegexInputWindow regexInput = new InstruRegexInputWindow();
|
||||
regexInput.open(traceDialogRef, settingsData.classRegex);
|
||||
}
|
||||
});
|
||||
|
|
@ -134,6 +150,7 @@ public class TraceWindow
|
|||
toggleAllowJarInstru.setLayoutData(gridData5);
|
||||
toggleAllowJarInstru.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.allowJarsToBeTraced, "[instrujars-true", "[instrujars-false");
|
||||
|
|
@ -144,6 +161,7 @@ public class TraceWindow
|
|||
toggleSaveClassFiles.setLayoutData(gridData6);
|
||||
toggleSaveClassFiles.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.saveTracedClassfiles, "[saveinstru-true", "[saveinstru-false");
|
||||
|
|
@ -154,6 +172,7 @@ public class TraceWindow
|
|||
toggleVerboseMode.setLayoutData(gridData7);
|
||||
toggleVerboseMode.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.verboseMode, "[verbose-true", "[verbose-false");
|
||||
|
|
@ -164,6 +183,7 @@ public class TraceWindow
|
|||
traceSettingsLabel.setText("Trace Settings:");
|
||||
sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter()
|
||||
{
|
||||
@Override
|
||||
public void shellClosed(org.eclipse.swt.events.ShellEvent e)
|
||||
{
|
||||
disconnect();
|
||||
|
|
@ -175,18 +195,20 @@ public class TraceWindow
|
|||
toggleEntryExitButton.setText(ClientStrings.ENABLE_EE_TRACE);
|
||||
toggleEntryExitButton.setLayoutData(gridData2);
|
||||
toggleEntryExitButton
|
||||
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.entryExitEnabled, "[trace-ee-true", "[trace-ee-false");
|
||||
}
|
||||
});
|
||||
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.entryExitEnabled, "[trace-ee-true", "[trace-ee-false");
|
||||
}
|
||||
});
|
||||
toggleBranchButton = new Button(sShell, SWT.LEFT);
|
||||
toggleBranchButton.setText(ClientStrings.ENABLE_BRANCH_TRACE);
|
||||
toggleBranchButton.setLayoutData(gridData1);
|
||||
toggleBranchButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.branchEnabled, "[trace-branch-true", "[trace-branch-false");
|
||||
|
|
@ -195,47 +217,72 @@ public class TraceWindow
|
|||
toggleArgsButton = new Button(sShell, SWT.LEFT);
|
||||
toggleArgsButton.setText(ClientStrings.ENABLE_ARGS_TRACE);
|
||||
toggleArgsButton.setLayoutData(gridData21);
|
||||
callersLabel = new Label(sShell, SWT.NONE);
|
||||
callersLabel.setText("Callers Settings:");
|
||||
callersStateButton = new Button(sShell, SWT.NONE);
|
||||
callersStateButton.setLayoutData(gridData12);
|
||||
callersStateButton.setText(ClientStrings.BEGIN_CAPTURE_CALLERS);
|
||||
callersStateButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
if (!settingsData.callersCaptureInProgress)
|
||||
{
|
||||
CallersRegexInputWindow regexInput = new CallersRegexInputWindow();
|
||||
regexInput.open(traceDialogRef, settingsData.callersRegex);
|
||||
}
|
||||
else
|
||||
{
|
||||
toggleSetting(settingsData.callersCaptureInProgress, "[callers-enabled-true", "[callers-enabled-false");
|
||||
}
|
||||
}
|
||||
});
|
||||
outputSettingsLabel = new Label(sShell, SWT.NONE);
|
||||
outputSettingsLabel.setText("Output Modes:");
|
||||
toggleArgsButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.argsEnabled, "[trace-args-true", "[trace-args-false");
|
||||
}
|
||||
});
|
||||
toggleStdOutButton = new Button(sShell, SWT.LEFT);
|
||||
toggleStdOutButton.setText(ClientStrings.ENABLE_STDOUT_TRACE);
|
||||
toggleStdOutButton.setText(ClientStrings.ENABLE_STDOUT_OUTPUT);
|
||||
toggleStdOutButton.setLayoutData(gridData4);
|
||||
toggleFileOutputButton = new Button(sShell, SWT.LEFT);
|
||||
toggleFileOutputButton.setText(ClientStrings.ENABLE_FILE_TRACE);
|
||||
toggleFileOutputButton.setText(ClientStrings.ENABLE_FILE_OUTPUT);
|
||||
toggleFileOutputButton.setLayoutData(gridData11);
|
||||
toggleNetworkTraceButton = new Button(sShell, SWT.LEFT);
|
||||
toggleNetworkTraceButton.setText(ClientStrings.ENABLE_NETWORK_TRACE);
|
||||
toggleNetworkTraceButton.setText(ClientStrings.ENABLE_NETWORK_OUTPUT);
|
||||
toggleNetworkTraceButton.setLayoutData(gridData22);
|
||||
toggleNetworkTraceButton
|
||||
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleNetworkTrace();
|
||||
}
|
||||
});
|
||||
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleNetworkTrace();
|
||||
}
|
||||
});
|
||||
toggleFileOutputButton
|
||||
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.fileOutEnabled, "[trace-file-true", "[trace-file-false");
|
||||
}
|
||||
});
|
||||
.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.fileOutEnabled, "[out-file-true", "[out-file-false");
|
||||
}
|
||||
});
|
||||
spacerLabel = new Label(sShell, SWT.NONE);
|
||||
spacerLabel.setText("");
|
||||
toggleStdOutButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
toggleSetting(settingsData.stdOutEnabled, "[trace-stdout-true", "[trace-stdout-false");
|
||||
toggleSetting(settingsData.stdOutEnabled, "[out-stdout-true", "[out-stdout-false");
|
||||
}
|
||||
});
|
||||
disconnectButton = new Button(sShell, SWT.LEFT);
|
||||
|
|
@ -243,6 +290,7 @@ public class TraceWindow
|
|||
disconnectButton.setLayoutData(gridData);
|
||||
disconnectButton.addMouseListener(new org.eclipse.swt.events.MouseAdapter()
|
||||
{
|
||||
@Override
|
||||
public void mouseUp(org.eclipse.swt.events.MouseEvent e)
|
||||
{
|
||||
sShell.close();
|
||||
|
|
@ -251,7 +299,7 @@ public class TraceWindow
|
|||
}
|
||||
|
||||
/**
|
||||
* This method initializes composite
|
||||
* This method initializes composite
|
||||
*
|
||||
*/
|
||||
private void createComposite()
|
||||
|
|
@ -262,14 +310,12 @@ public class TraceWindow
|
|||
gridData3.grabExcessVerticalSpace = true;
|
||||
gridData3.heightHint = 99999;
|
||||
gridData3.widthHint = 99999;
|
||||
gridData3.verticalSpan = 17;
|
||||
gridData3.verticalSpan = 19;
|
||||
gridData3.grabExcessHorizontalSpace = true;
|
||||
composite = new Composite(sShell, SWT.NONE);
|
||||
composite.setLayoutData(gridData3);
|
||||
composite.setLayout(fillLayout);
|
||||
statusTextArea = new Text(composite, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
|
||||
statusTextArea.setEditable(false);
|
||||
statusTextArea.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
|
||||
createOutputTabFolder();
|
||||
}
|
||||
|
||||
public void open()
|
||||
|
|
@ -277,9 +323,9 @@ public class TraceWindow
|
|||
createSShell();
|
||||
sShell.open();
|
||||
addMessage("*** Connected!");
|
||||
controlThread.sendMessage("getsettings");
|
||||
controlThread.sendMessage("getsettings");
|
||||
}
|
||||
|
||||
|
||||
public void disconnect()
|
||||
{
|
||||
controlThread.disconnect();
|
||||
|
|
@ -288,63 +334,63 @@ public class TraceWindow
|
|||
networkTraceThread.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void toggleNetworkTrace()
|
||||
{
|
||||
sShell.getDisplay().asyncExec(new Runnable()
|
||||
{
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
disableButtons();
|
||||
if (!networkTraceEnabled)
|
||||
{
|
||||
controlThread.sendMessage("[trace-network");
|
||||
controlThread.sendMessage("[out-network");
|
||||
String networkTracePortStr = controlThread.getMessage();
|
||||
int networkTracePort = Integer.parseInt(networkTracePortStr);
|
||||
try
|
||||
{
|
||||
networkTraceThread = new NetworkTraceReceiverThread(remoteAddress, networkTracePort, traceDialogRef);
|
||||
{
|
||||
networkTraceThread = new NetworkDataReceiverThread(remoteAddress, networkTracePort, traceDialogRef);
|
||||
networkTraceThread.start();
|
||||
networkTraceEnabled = true;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
addMessage("*** Failed to setup network trace: " + ex.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
networkTraceThread.disconnect();
|
||||
networkTraceEnabled = false;
|
||||
}
|
||||
updateButtonText();
|
||||
}
|
||||
updateButtonText();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void setRegex(final String regex)
|
||||
{
|
||||
sShell.getDisplay().asyncExec(new Runnable()
|
||||
{
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
disableButtons();
|
||||
controlThread.sendMessage("[regex-" + regex);
|
||||
controlThread.sendMessage("getsettings");
|
||||
disableButtons();
|
||||
controlThread.sendMessage("[regex-" + regex);
|
||||
controlThread.sendMessage("getsettings");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void toggleSetting(final boolean settingValue, final String enableCommand, final String disableCommand)
|
||||
{
|
||||
sShell.getDisplay().asyncExec(new Runnable()
|
||||
{
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
disableButtons();
|
||||
disableButtons();
|
||||
if (settingValue)
|
||||
{
|
||||
controlThread.sendMessage(disableCommand);
|
||||
|
|
@ -353,11 +399,11 @@ public class TraceWindow
|
|||
{
|
||||
controlThread.sendMessage(enableCommand);
|
||||
}
|
||||
controlThread.sendMessage("getsettings");
|
||||
controlThread.sendMessage("getsettings");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void disableButtons()
|
||||
{
|
||||
toggleInstrumentEnabled.setEnabled(false);
|
||||
|
|
@ -365,14 +411,18 @@ public class TraceWindow
|
|||
toggleAllowJarInstru.setEnabled(false);
|
||||
toggleSaveClassFiles.setEnabled(false);
|
||||
toggleVerboseMode.setEnabled(false);
|
||||
|
||||
toggleEntryExitButton.setEnabled(false);
|
||||
toggleBranchButton.setEnabled(false);
|
||||
toggleArgsButton.setEnabled(false);
|
||||
|
||||
callersStateButton.setEnabled(false);
|
||||
|
||||
toggleStdOutButton.setEnabled(false);
|
||||
toggleFileOutputButton.setEnabled(false);
|
||||
toggleNetworkTraceButton.setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
private void chooseText(Button control, boolean option, String enabledText, String disabledText)
|
||||
{
|
||||
if (option)
|
||||
|
|
@ -385,47 +435,122 @@ public class TraceWindow
|
|||
}
|
||||
control.setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
private void updateButtonText()
|
||||
{
|
||||
addMessage("*** Latest Settings Received");
|
||||
|
||||
|
||||
chooseText(toggleInstrumentEnabled, settingsData.instrEnabled, ClientStrings.ENABLE_INSTR, ClientStrings.DISABLE_INSTR);
|
||||
chooseText(toggleAllowJarInstru, settingsData.allowJarsToBeTraced, ClientStrings.ENABLE_ALLOWJARS, ClientStrings.DISABLE_ALLOWJARS);
|
||||
chooseText(toggleSaveClassFiles, settingsData.saveTracedClassfiles, ClientStrings.ENABLE_SAVECLASSES, ClientStrings.DISABLE_SAVECLASSES);
|
||||
chooseText(toggleVerboseMode, settingsData.verboseMode, ClientStrings.ENABLE_VERBOSEMODE, ClientStrings.DISABLE_VERBOSEMODE);
|
||||
|
||||
chooseText(toggleEntryExitButton, settingsData.entryExitEnabled, ClientStrings.ENABLE_EE_TRACE, ClientStrings.DISABLE_EE_TRACE);
|
||||
chooseText(toggleBranchButton, settingsData.branchEnabled, ClientStrings.ENABLE_BRANCH_TRACE, ClientStrings.DISABLE_BRANCH_TRACE);
|
||||
chooseText(toggleArgsButton, settingsData.argsEnabled, ClientStrings.ENABLE_ARGS_TRACE, ClientStrings.DISABLE_ARGS_TRACE);
|
||||
chooseText(toggleStdOutButton, settingsData.stdOutEnabled, ClientStrings.ENABLE_STDOUT_TRACE, ClientStrings.DISABLE_STDOUT_TRACE);
|
||||
chooseText(toggleFileOutputButton, settingsData.fileOutEnabled, ClientStrings.ENABLE_FILE_TRACE, ClientStrings.DISABLE_FILE_TRACE);
|
||||
chooseText(toggleNetworkTraceButton, networkTraceEnabled, ClientStrings.ENABLE_NETWORK_TRACE, ClientStrings.DISABLE_NETWORK_TRACE);
|
||||
|
||||
chooseText(callersStateButton, settingsData.callersCaptureInProgress, ClientStrings.BEGIN_CAPTURE_CALLERS, ClientStrings.END_CAPTURE_CALLERS);
|
||||
|
||||
chooseText(toggleStdOutButton, settingsData.stdOutEnabled, ClientStrings.ENABLE_STDOUT_OUTPUT, ClientStrings.DISABLE_STDOUT_OUTPUT);
|
||||
chooseText(toggleFileOutputButton, settingsData.fileOutEnabled, ClientStrings.ENABLE_FILE_OUTPUT, ClientStrings.DISABLE_FILE_OUTPUT);
|
||||
chooseText(toggleNetworkTraceButton, networkTraceEnabled, ClientStrings.ENABLE_NETWORK_OUTPUT, ClientStrings.DISABLE_NETWORK_OUTPUT);
|
||||
setClassRegexButton.setEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setConfig(final Map<String, String> settingsMap)
|
||||
{
|
||||
sShell.getDisplay().asyncExec(new Runnable()
|
||||
{
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
addMessage("*** Fetch Settings");
|
||||
settingsData = new ParsedSettingsData(settingsMap);
|
||||
updateButtonText();
|
||||
updateButtonText();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void addMessage(final String message)
|
||||
{
|
||||
sShell.getDisplay().asyncExec(new Runnable()
|
||||
{
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
statusTextArea.append(message + "\n");
|
||||
statusTextArea.append(message + "\n");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes outputTabFolder
|
||||
*
|
||||
*/
|
||||
private void createOutputTabFolder()
|
||||
{
|
||||
outputTabFolder = new TabFolder(composite, SWT.NONE);
|
||||
statusTextArea = new Text(outputTabFolder, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER);
|
||||
statusTextArea.setEditable(false);
|
||||
statusTextArea.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
|
||||
callersTree = new Tree(outputTabFolder, SWT.BORDER);
|
||||
|
||||
textOutputTabItem = new TabItem(outputTabFolder, SWT.NONE);
|
||||
textOutputTabItem.setControl(statusTextArea);
|
||||
textOutputTabItem.setText("Text Output");
|
||||
callersOutputTabItem = new TabItem(outputTabFolder, SWT.NONE);
|
||||
callersOutputTabItem.setControl(callersTree);
|
||||
callersOutputTabItem.setText("Callers");
|
||||
}
|
||||
|
||||
public void setCallers(final Map<String, Object> callersMap)
|
||||
{
|
||||
callersMap.remove(CallersConfigConstants.MAP_ID);
|
||||
sShell.getDisplay().asyncExec(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
callersTree.removeAll();
|
||||
addCallersData(callersTree, callersMap);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void addCallersData(Object parentItem, Map<String, Object> callersMap)
|
||||
{
|
||||
for (Entry<String, Object> mapEntry : callersMap.entrySet())
|
||||
{
|
||||
String entryName = mapEntry.getKey();
|
||||
TreeItem item;
|
||||
if (parentItem instanceof Tree)
|
||||
{
|
||||
item = new TreeItem((Tree)parentItem, SWT.NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
item = new TreeItem((TreeItem)parentItem, SWT.NULL);
|
||||
}
|
||||
item.setText(entryName);
|
||||
Object entryValue = mapEntry.getValue();
|
||||
if (entryValue instanceof Map<?,?>)
|
||||
{
|
||||
Map<String, Object> entryMap = (Map<String, Object>)entryValue;
|
||||
if (entryMap.size() > 0)
|
||||
{
|
||||
addCallersData(item, entryMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCallersRegex(String regex)
|
||||
{
|
||||
if (!settingsData.callersCaptureInProgress)
|
||||
{
|
||||
controlThread.sendMessage("[callers-regex-" + regex);
|
||||
toggleSetting(settingsData.callersCaptureInProgress, "[callers-enabled-true", "[callers-enabled-false");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public class ControlConnectionThread implements Runnable
|
|||
private final BlockingQueue<String> outgoingMessages = new LinkedBlockingQueue<String>();
|
||||
private final ControlConnectionSenderThread senderThread = new ControlConnectionSenderThread();
|
||||
private Thread sendThread;
|
||||
|
||||
|
||||
public ControlConnectionThread(Socket socket, TraceWindow window)
|
||||
{
|
||||
this.window = window;
|
||||
|
|
@ -32,13 +32,13 @@ public class ControlConnectionThread implements Runnable
|
|||
receiveThread.setDaemon(true);
|
||||
receiveThread.setName("Control Receive Thread");
|
||||
receiveThread.start();
|
||||
|
||||
|
||||
sendThread = new Thread(senderThread);
|
||||
sendThread.setDaemon(true);
|
||||
sendThread.setName("Control Sender Thread");
|
||||
sendThread.start();
|
||||
}
|
||||
|
||||
|
||||
public String getMessage()
|
||||
{
|
||||
try
|
||||
|
|
@ -56,11 +56,11 @@ public class ControlConnectionThread implements Runnable
|
|||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
ObjectInputStream objIn = new ObjectInputStream(socket.getInputStream());
|
||||
Object receivedMessage = (Object)objIn.readObject();
|
||||
Object receivedMessage = objIn.readObject();
|
||||
if (receivedMessage instanceof Map<?,?>)
|
||||
{
|
||||
Map<String,String> settingsMap = (Map<String,String>)receivedMessage;
|
||||
|
|
@ -78,10 +78,10 @@ public class ControlConnectionThread implements Runnable
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
window.disconnect();
|
||||
window.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void disconnect()
|
||||
{
|
||||
if (sendThread != null)
|
||||
|
|
@ -107,11 +107,11 @@ public class ControlConnectionThread implements Runnable
|
|||
catch (InterruptedException e1)
|
||||
{
|
||||
// Throw away
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ControlConnectionSenderThread implements Runnable
|
||||
{
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
package org.intrace.client.gui.helper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.Map;
|
||||
|
||||
import org.intrace.client.gui.TraceWindow;
|
||||
|
||||
public class NetworkDataReceiverThread implements Runnable
|
||||
{
|
||||
private final Socket traceSocket;
|
||||
private final TraceWindow window;
|
||||
public NetworkDataReceiverThread(InetAddress address, int networkTracePort, TraceWindow window) throws IOException
|
||||
{
|
||||
this.window = window;
|
||||
traceSocket = new Socket();
|
||||
traceSocket.connect(new InetSocketAddress(address, networkTracePort));
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
Thread t = new Thread(this);
|
||||
t.setDaemon(true);
|
||||
t.setName("Network Data Receiver");
|
||||
t.start();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
ObjectInputStream objIn = new ObjectInputStream(traceSocket.getInputStream());
|
||||
while (true)
|
||||
{
|
||||
Object data = objIn.readObject();
|
||||
if (data instanceof String)
|
||||
{
|
||||
String traceLine = (String)data;
|
||||
window.addMessage(traceLine);
|
||||
}
|
||||
else if (data instanceof Map<?,?>)
|
||||
{
|
||||
Map<String,Object> callersMap = (Map<String,Object>)data;
|
||||
window.setCallers(callersMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
traceSocket.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,8 +3,10 @@ package org.intrace.client.gui.helper;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import org.intrace.agent.AgentConfigConstants;
|
||||
import org.intrace.output.trace.TraceConfigConstants;
|
||||
import org.intrace.shared.AgentConfigConstants;
|
||||
import org.intrace.shared.CallersConfigConstants;
|
||||
import org.intrace.shared.OutputConfigConstants;
|
||||
import org.intrace.shared.TraceConfigConstants;
|
||||
|
||||
public class ParsedSettingsData
|
||||
{
|
||||
|
|
@ -13,16 +15,19 @@ public class ParsedSettingsData
|
|||
public final boolean saveTracedClassfiles;
|
||||
public final boolean verboseMode;
|
||||
public final boolean allowJarsToBeTraced;
|
||||
|
||||
|
||||
public final boolean callersCaptureInProgress;
|
||||
|
||||
public final boolean entryExitEnabled;
|
||||
public final boolean branchEnabled;
|
||||
public final boolean argsEnabled;
|
||||
public final boolean stdOutEnabled;
|
||||
public final boolean fileOutEnabled;
|
||||
public final String callersRegex;
|
||||
public ParsedSettingsData(Map<String, String> settingsMap)
|
||||
{
|
||||
classRegex = settingsMap.get(AgentConfigConstants.CLASS_REGEX);
|
||||
|
||||
|
||||
if ("true".equals(settingsMap.get(AgentConfigConstants.TRACING_ENABLED)))
|
||||
{
|
||||
instrEnabled = true;
|
||||
|
|
@ -31,7 +36,7 @@ public class ParsedSettingsData
|
|||
{
|
||||
instrEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
if ("true".equals(settingsMap.get(AgentConfigConstants.SAVE_TRACED_CLASSFILES)))
|
||||
{
|
||||
saveTracedClassfiles = true;
|
||||
|
|
@ -40,7 +45,7 @@ public class ParsedSettingsData
|
|||
{
|
||||
saveTracedClassfiles = false;
|
||||
}
|
||||
|
||||
|
||||
if ("true".equals(settingsMap.get(AgentConfigConstants.VERBOSE_MODE)))
|
||||
{
|
||||
verboseMode = true;
|
||||
|
|
@ -49,7 +54,7 @@ public class ParsedSettingsData
|
|||
{
|
||||
verboseMode = false;
|
||||
}
|
||||
|
||||
|
||||
if ("true".equals(settingsMap.get(AgentConfigConstants.ALLOW_JARS_TO_BE_TRACED)))
|
||||
{
|
||||
allowJarsToBeTraced = true;
|
||||
|
|
@ -58,7 +63,18 @@ public class ParsedSettingsData
|
|||
{
|
||||
allowJarsToBeTraced = false;
|
||||
}
|
||||
|
||||
|
||||
callersRegex = settingsMap.get(CallersConfigConstants.PATTERN);
|
||||
|
||||
if ("true".equals(settingsMap.get(CallersConfigConstants.CALLERS_ENABLED)))
|
||||
{
|
||||
callersCaptureInProgress = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
callersCaptureInProgress = false;
|
||||
}
|
||||
|
||||
if ("true".equals(settingsMap.get(TraceConfigConstants.ENTRY_EXIT)))
|
||||
{
|
||||
entryExitEnabled = true;
|
||||
|
|
@ -67,7 +83,7 @@ public class ParsedSettingsData
|
|||
{
|
||||
entryExitEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
if ("true".equals(settingsMap.get(TraceConfigConstants.BRANCH)))
|
||||
{
|
||||
branchEnabled = true;
|
||||
|
|
@ -76,7 +92,7 @@ public class ParsedSettingsData
|
|||
{
|
||||
branchEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
if ("true".equals(settingsMap.get(TraceConfigConstants.ARG)))
|
||||
{
|
||||
argsEnabled = true;
|
||||
|
|
@ -85,8 +101,8 @@ public class ParsedSettingsData
|
|||
{
|
||||
argsEnabled = false;
|
||||
}
|
||||
|
||||
if ("true".equals(settingsMap.get(TraceConfigConstants.STD_OUT)))
|
||||
|
||||
if ("true".equals(settingsMap.get(OutputConfigConstants.STD_OUT)))
|
||||
{
|
||||
stdOutEnabled = true;
|
||||
}
|
||||
|
|
@ -94,8 +110,8 @@ public class ParsedSettingsData
|
|||
{
|
||||
stdOutEnabled = false;
|
||||
}
|
||||
|
||||
if ("true".equals(settingsMap.get(TraceConfigConstants.FILE_OUT)))
|
||||
|
||||
if ("true".equals(settingsMap.get(OutputConfigConstants.FILE_OUT)))
|
||||
{
|
||||
fileOutEnabled = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,343 @@
|
|||
package org.intrace.output;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.ServerSocket;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Static implementation of the TraceWriter interface
|
||||
*/
|
||||
public class AgentHelper
|
||||
{
|
||||
public static final Map<IOutput,Object> outputHandlers = new ConcurrentHashMap<IOutput,Object>();
|
||||
|
||||
private static OutputSettings outputSettings = new OutputSettings("");
|
||||
private static boolean file1Active = true;
|
||||
private static int writtenChars = 0;
|
||||
private static final int MAX_CHARS_PER_FILE = 100 * 1000; // 100kb
|
||||
|
||||
private static final Map<NetworkDataSenderThread,Object> networkOutputThreads = new ConcurrentHashMap<NetworkDataSenderThread,Object>();
|
||||
|
||||
public static List<String> getResponses(String agentArgs)
|
||||
{
|
||||
List<String> responses = new ArrayList<String>();
|
||||
String response = getResponse(agentArgs);
|
||||
if (response != null)
|
||||
{
|
||||
responses.add(response);
|
||||
}
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
response = outputHandler.getResponse(agentArgs);
|
||||
if (response != null)
|
||||
{
|
||||
responses.add(response);
|
||||
}
|
||||
}
|
||||
return responses;
|
||||
}
|
||||
|
||||
private static String getResponse(String args)
|
||||
{
|
||||
boolean oldStdOutEnabled = outputSettings.isStdoutTraceOutputEnabled();
|
||||
boolean oldFileOutEnabled = outputSettings.isFileTraceOutputEnabled();
|
||||
outputSettings.parseArgs(args);
|
||||
|
||||
if ((oldStdOutEnabled != outputSettings.isStdoutTraceOutputEnabled()) ||
|
||||
(oldFileOutEnabled != outputSettings.isFileTraceOutputEnabled()))
|
||||
{
|
||||
System.out.println("## Output Settings Changed");
|
||||
}
|
||||
|
||||
if (outputSettings.networkTraceOutputRequested)
|
||||
{
|
||||
System.out.println("## Network Output Requested");
|
||||
ServerSocket networkSocket;
|
||||
try
|
||||
{
|
||||
networkSocket = new ServerSocket(0);
|
||||
NetworkDataSenderThread networkOutputThread = new NetworkDataSenderThread(networkSocket);
|
||||
|
||||
networkOutputThreads.put(networkOutputThread, new Object());
|
||||
|
||||
networkOutputThread.start(networkOutputThreads.keySet());
|
||||
outputSettings.networkTraceOutputRequested = false;
|
||||
return Integer.toString(networkSocket.getLocalPort());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Do nothing
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, String> getSettings()
|
||||
{
|
||||
Map<String, String> settings = new HashMap<String, String>();
|
||||
settings.putAll(outputSettings.getSettingsMap());
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
settings.putAll(outputHandler.getSettingsMap());
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write output
|
||||
*
|
||||
* @param xiTrace
|
||||
*/
|
||||
public static void writeOutput(String xiOutput)
|
||||
{
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat();
|
||||
long threadID = Thread.currentThread().getId();
|
||||
String traceString = "[" + dateFormat.format(new Date()) + "]:[" +
|
||||
threadID + "]:" + xiOutput;
|
||||
if (outputSettings.isStdoutTraceOutputEnabled())
|
||||
{
|
||||
System.out.println(traceString);
|
||||
}
|
||||
|
||||
if (outputSettings.isFileTraceOutputEnabled())
|
||||
{
|
||||
writeFileTrace(traceString);
|
||||
}
|
||||
|
||||
Set<NetworkDataSenderThread> networkThreads = networkOutputThreads.keySet();
|
||||
if (networkThreads.size() > 0)
|
||||
{
|
||||
for (NetworkDataSenderThread thread : networkThreads)
|
||||
{
|
||||
thread.queueData(traceString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data output
|
||||
*
|
||||
* @param xiTrace
|
||||
*/
|
||||
public static void writeDataOutput(Object xiOutput)
|
||||
{
|
||||
Set<NetworkDataSenderThread> networkThreads = networkOutputThreads.keySet();
|
||||
if (networkThreads.size() > 0)
|
||||
{
|
||||
for (NetworkDataSenderThread thread : networkThreads)
|
||||
{
|
||||
thread.queueData(xiOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized void writeFileTrace(String traceString)
|
||||
{
|
||||
PrintWriter outputWriter;
|
||||
if (file1Active)
|
||||
{
|
||||
outputWriter = outputSettings.getFile1TraceWriter();
|
||||
}
|
||||
else
|
||||
{
|
||||
outputWriter = outputSettings.getFile2TraceWriter();
|
||||
}
|
||||
outputWriter.println(traceString);
|
||||
outputWriter.flush();
|
||||
|
||||
// Switch trace files if necessary
|
||||
writtenChars += traceString.length();
|
||||
if (writtenChars > MAX_CHARS_PER_FILE)
|
||||
{
|
||||
writtenChars = 0;
|
||||
outputSettings.resetTraceFiles(file1Active, !file1Active);
|
||||
file1Active = !file1Active;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* STATIC IMPLEMENTATION OF IOutput
|
||||
*/
|
||||
|
||||
public static void enter(String className, String methodName)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.enter(className, methodName);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, byte byteArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, byteArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, byte[] byteArrayArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, byteArrayArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, short shortArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, shortArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, short[] shortArrayArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, shortArrayArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, int intArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, intArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, int[] intArrayArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, intArrayArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, long longArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, longArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, long[] longArrayArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, longArrayArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, float floatArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, floatArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, float[] floatArrayArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, floatArrayArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, double doubleArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, doubleArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, double[] doubleArrayArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, doubleArrayArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, boolean boolArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, boolArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, boolean[] boolArrayArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, boolArrayArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, char charArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, charArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, char[] charArrayArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, charArrayArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, Object objArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, objArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void arg(String className, String methodName, Object[] objArrayArg)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.arg(className, methodName, objArrayArg);
|
||||
}
|
||||
}
|
||||
|
||||
public static void branch(String className, String methodName, int lineNo)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.branch(className, methodName, lineNo);
|
||||
}
|
||||
}
|
||||
|
||||
public static void exit(String className, String methodName, int lineNo)
|
||||
{
|
||||
for (IOutput outputHandler : outputHandlers.keySet())
|
||||
{
|
||||
outputHandler.exit(className, methodName, lineNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,33 +8,33 @@ import java.util.Map;
|
|||
public interface IOutput
|
||||
{
|
||||
public void enter(String className, String methodName);
|
||||
|
||||
|
||||
public void arg(String className, String methodName, byte byteArg);
|
||||
public void arg(String className, String methodName, byte[] byteArrayArg);
|
||||
public void arg(String className, String methodName, short shortArg);
|
||||
public void arg(String className, String methodName, short[] shortArrayArg);
|
||||
|
||||
|
||||
public void arg(String className, String methodName, int intArg);
|
||||
public void arg(String className, String methodName, int[] intArrayArg);
|
||||
public void arg(String className, String methodName, long longArg);
|
||||
public void arg(String className, String methodName, long[] longArrayArg);
|
||||
|
||||
|
||||
public void arg(String className, String methodName, float floatArg);
|
||||
public void arg(String className, String methodName, float[] floatArrayArg);
|
||||
public void arg(String className, String methodName, double doubleArg);
|
||||
public void arg(String className, String methodName, double[] doubleArrayArg);
|
||||
|
||||
|
||||
public void arg(String className, String methodName, boolean boolArg);
|
||||
public void arg(String className, String methodName, boolean[] boolArrayArg);
|
||||
public void arg(String className, String methodName, char charArg);
|
||||
public void arg(String className, String methodName, char[] charArrayArg);
|
||||
|
||||
|
||||
public void arg(String className, String methodName, Object objArg);
|
||||
public void arg(String className, String methodName, Object[] objArrayArg);
|
||||
|
||||
|
||||
public void branch(String className, String methodName, int lineNo);
|
||||
public void exit(String className, String methodName, int lineNo);
|
||||
|
||||
public String getResponse(String args);
|
||||
|
||||
public String getResponse(String args);
|
||||
public Map<String,String> getSettingsMap();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,147 @@
|
|||
package org.intrace.output;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class IOutputAdapter implements IOutput
|
||||
{
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, byte byteArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, byte[] byteArrayArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, short shortArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, short[] shortArrayArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, int intArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, int[] intArrayArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, long longArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, long[] longArrayArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, float floatArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, float[] floatArrayArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, double doubleArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, double[] doubleArrayArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, boolean boolArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, boolean[] boolArrayArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, char charArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, char[] charArrayArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, Object objArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, Object[] objArrayArg)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void branch(String className, String methodName, int lineNo)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter(String className, String methodName)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit(String className, String methodName, int lineNo)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getResponse(String args)
|
||||
{
|
||||
// Do nothing
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getSettingsMap()
|
||||
{
|
||||
return new HashMap<String, String>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package org.intrace.output;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
public class NetworkDataSenderThread implements Runnable
|
||||
{
|
||||
private final ServerSocket networkSocket;
|
||||
private final BlockingQueue<Object> outgoingData = new LinkedBlockingQueue<Object>(100);
|
||||
private Set<NetworkDataSenderThread> set;
|
||||
|
||||
public NetworkDataSenderThread(ServerSocket networkSocket)
|
||||
{
|
||||
this.networkSocket = networkSocket;
|
||||
}
|
||||
|
||||
public void start(Set<NetworkDataSenderThread> set)
|
||||
{
|
||||
this.set = set;
|
||||
|
||||
Thread networkThread = new Thread(this);
|
||||
networkThread.setDaemon(true);
|
||||
networkThread.setName("Network Data Sender");
|
||||
networkThread.start();
|
||||
}
|
||||
|
||||
private void stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
networkSocket.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Throw away
|
||||
}
|
||||
set.remove(this);
|
||||
System.out.println("## Network Data Connection Disconnected");
|
||||
}
|
||||
|
||||
public void queueData(Object data)
|
||||
{
|
||||
try
|
||||
{
|
||||
outgoingData.put(data);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
// Throw away
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
Socket traceSendingSocket;
|
||||
try
|
||||
{
|
||||
traceSendingSocket = networkSocket.accept();
|
||||
try
|
||||
{
|
||||
ObjectOutputStream traceWriter = new ObjectOutputStream(traceSendingSocket.getOutputStream());
|
||||
while (true)
|
||||
{
|
||||
Object traceLine = outgoingData.take();
|
||||
traceWriter.writeObject(traceLine);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
traceSendingSocket.close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
package org.intrace.output;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.intrace.shared.OutputConfigConstants;
|
||||
|
||||
public class OutputSettings
|
||||
{
|
||||
private boolean stdoutTraceOutputEnabled = true;
|
||||
private boolean fileTraceOutputEnabled = false;
|
||||
private File file1;
|
||||
private File file2;
|
||||
private PrintWriter file1TraceWriter;
|
||||
private PrintWriter file2TraceWriter;
|
||||
|
||||
public boolean networkTraceOutputRequested = false;
|
||||
|
||||
public OutputSettings(String args)
|
||||
{
|
||||
file1 = new File("trc1.txt");
|
||||
file2 = new File("trc2.txt");
|
||||
resetTraceFiles(true, true);
|
||||
parseArgs(args);
|
||||
}
|
||||
|
||||
public void parseArgs(String args)
|
||||
{
|
||||
String[] seperateArgs = args.split("\\[");
|
||||
for (int ii = 0; ii < seperateArgs.length; ii++)
|
||||
{
|
||||
parseArg(seperateArgs[ii].toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
private void parseArg(String arg)
|
||||
{
|
||||
if (arg.equals("out-stdout-true"))
|
||||
{
|
||||
stdoutTraceOutputEnabled = true;
|
||||
}
|
||||
else if (arg.equals("out-stdout-false"))
|
||||
{
|
||||
stdoutTraceOutputEnabled = false;
|
||||
}
|
||||
else if (arg.equals("out-file-true"))
|
||||
{
|
||||
fileTraceOutputEnabled = true;
|
||||
}
|
||||
else if (arg.equals("out-file-false"))
|
||||
{
|
||||
fileTraceOutputEnabled = false;
|
||||
}
|
||||
else if (arg.startsWith("out-file1-"))
|
||||
{
|
||||
String file1Name = arg.replace("out-file1-", "");
|
||||
file1 = new File(file1Name);
|
||||
resetTraceFiles(true, false);
|
||||
}
|
||||
else if (arg.startsWith("out-file2-"))
|
||||
{
|
||||
String file2Name = arg.replace("out-file2-", "");
|
||||
file2 = new File(file2Name);
|
||||
resetTraceFiles(false, true);
|
||||
}
|
||||
else if (arg.equals("out-network"))
|
||||
{
|
||||
networkTraceOutputRequested = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void resetTraceFiles(boolean resetFile1, boolean resetFile2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (resetFile1)
|
||||
{
|
||||
file1.delete();
|
||||
file1TraceWriter = new PrintWriter(new FileWriter(file1));
|
||||
}
|
||||
if (resetFile2)
|
||||
{
|
||||
file2.delete();
|
||||
file2TraceWriter = new PrintWriter(new FileWriter(file2));
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Throw away
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isStdoutTraceOutputEnabled()
|
||||
{
|
||||
return stdoutTraceOutputEnabled;
|
||||
}
|
||||
|
||||
public boolean isFileTraceOutputEnabled()
|
||||
{
|
||||
return fileTraceOutputEnabled;
|
||||
}
|
||||
|
||||
public PrintWriter getFile1TraceWriter()
|
||||
{
|
||||
return file1TraceWriter;
|
||||
}
|
||||
|
||||
public PrintWriter getFile2TraceWriter()
|
||||
{
|
||||
return file2TraceWriter;
|
||||
}
|
||||
|
||||
public Map<String,String> getSettingsMap()
|
||||
{
|
||||
Map<String,String> settingsMap = new HashMap<String, String>();
|
||||
settingsMap.put(OutputConfigConstants.STD_OUT, Boolean.toString(stdoutTraceOutputEnabled));
|
||||
settingsMap.put(OutputConfigConstants.FILE_OUT, Boolean.toString(fileTraceOutputEnabled));
|
||||
return settingsMap;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package org.intrace.output.callers;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.intrace.output.AgentHelper;
|
||||
import org.intrace.output.IOutputAdapter;
|
||||
import org.intrace.shared.CallersConfigConstants;
|
||||
|
||||
public class CallersOutput extends IOutputAdapter
|
||||
{
|
||||
private final CallersSettings callersSettings = new CallersSettings("");
|
||||
private final Map<String, Object> recordedData = new ConcurrentHashMap<String, Object>();
|
||||
|
||||
@Override
|
||||
public synchronized String getResponse(String args)
|
||||
{
|
||||
CallersSettings oldSettings = new CallersSettings(callersSettings);
|
||||
callersSettings.parseArgs(args);
|
||||
|
||||
if (oldSettings.isCallersEnabled() != callersSettings.isCallersEnabled())
|
||||
{
|
||||
if (callersSettings.isCallersEnabled())
|
||||
{
|
||||
System.out.println("## Callers Analysis Started");
|
||||
recordedData.clear();
|
||||
recordedData.put(CallersConfigConstants.MAP_ID, CallersConfigConstants.MAP_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println("## Callers Analysis Ended");
|
||||
AgentHelper.writeDataOutput(new ConcurrentHashMap<String, Object>(recordedData));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getSettingsMap()
|
||||
{
|
||||
return callersSettings.getSettingsMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enter(String className, String methodName)
|
||||
{
|
||||
if (callersSettings.isCallersEnabled()
|
||||
&& callersSettings.getMethodRegex().matcher(methodName).matches())
|
||||
{
|
||||
recordCall();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private synchronized void recordCall()
|
||||
{
|
||||
StackTraceElement[] stackTrace = new Exception().getStackTrace();
|
||||
if ((stackTrace != null) && (stackTrace.length > 3))
|
||||
{
|
||||
Map<String, Object> treeElement = recordedData;
|
||||
for (int ii = 3; ii < stackTrace.length; ii++)
|
||||
{
|
||||
StackTraceElement element = stackTrace[ii];
|
||||
String stackLine = element.getClassName() + "#"
|
||||
+ element.getMethodName() + ":"
|
||||
+ ((element.getLineNumber() > -1) ? element.getLineNumber() : "unknown") ;
|
||||
|
||||
Object treeElementObj = treeElement.get(stackLine);
|
||||
if (treeElementObj == null)
|
||||
{
|
||||
treeElementObj = new ConcurrentHashMap<String, Object>();
|
||||
treeElement.put(stackLine, treeElementObj);
|
||||
}
|
||||
treeElement = (Map<String, Object>)treeElementObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package org.intrace.output.callers;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.intrace.shared.CallersConfigConstants;
|
||||
|
||||
public class CallersSettings
|
||||
{
|
||||
private boolean callersEnabled = false;
|
||||
private Pattern methodsPattern = Pattern.compile(".*");
|
||||
|
||||
public CallersSettings(CallersSettings oldSettings)
|
||||
{
|
||||
callersEnabled = oldSettings.callersEnabled;
|
||||
methodsPattern = oldSettings.methodsPattern;
|
||||
}
|
||||
|
||||
public CallersSettings(String args)
|
||||
{
|
||||
parseArgs(args);
|
||||
}
|
||||
|
||||
public void parseArgs(String args)
|
||||
{
|
||||
String[] seperateArgs = args.split("\\[");
|
||||
for (int ii = 0; ii < seperateArgs.length; ii++)
|
||||
{
|
||||
parseArg(seperateArgs[ii]);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseArg(String arg)
|
||||
{
|
||||
if (arg.toLowerCase().equals("callers-enabled-false"))
|
||||
{
|
||||
callersEnabled = false;
|
||||
}
|
||||
else if (arg.toLowerCase().equals("callers-enabled-true"))
|
||||
{
|
||||
callersEnabled = true;
|
||||
}
|
||||
else if (arg.startsWith("callers-regex-"))
|
||||
{
|
||||
String methodsRegexStr = arg.replace("callers-regex-", "");
|
||||
methodsPattern = Pattern.compile(methodsRegexStr);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCallersEnabled()
|
||||
{
|
||||
return callersEnabled;
|
||||
}
|
||||
|
||||
public Pattern getMethodRegex()
|
||||
{
|
||||
return methodsPattern;
|
||||
}
|
||||
|
||||
public Map<String,String> getSettingsMap()
|
||||
{
|
||||
Map<String,String> settingsMap = new HashMap<String, String>();
|
||||
settingsMap.put(CallersConfigConstants.CALLERS_ENABLED, Boolean.toString(callersEnabled));
|
||||
settingsMap.put(CallersConfigConstants.PATTERN, methodsPattern.pattern());
|
||||
return settingsMap;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package org.intrace.output.trace;
|
||||
|
||||
public class TraceConfigConstants
|
||||
{
|
||||
public static final String ENTRY_EXIT = "TRACE_ENTRY_EXIT";
|
||||
public static final String BRANCH = "TRACE_BRANCH";
|
||||
public static final String ARG = "TRACE_ARG";
|
||||
public static final String STD_OUT = "TRACE_STD_OUT";
|
||||
public static final String FILE_OUT = "TRACE_FILE_OUT";
|
||||
}
|
||||
|
|
@ -1,16 +1,10 @@
|
|||
package org.intrace.output.trace;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.ServerSocket;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.intrace.output.AgentHelper;
|
||||
import org.intrace.output.IOutput;
|
||||
|
||||
/**
|
||||
|
|
@ -22,16 +16,8 @@ public class TraceOutput implements IOutput
|
|||
private boolean branchTrace = false;
|
||||
private boolean argTrace = false;
|
||||
|
||||
private boolean stdoutTrace = true;
|
||||
private boolean fileoutTrace = false;
|
||||
private boolean file1Active = true;
|
||||
private int writtenChars = 0;
|
||||
private final int MAX_CHARS_PER_FILE = 100 * 1000; // 100kb
|
||||
|
||||
final TraceSettings traceSettings = new TraceSettings("");
|
||||
|
||||
private Map<NetworkTraceSenderThread,Object> traceThreads = new ConcurrentHashMap<NetworkTraceSenderThread,Object>();
|
||||
|
||||
public String getResponse(String args)
|
||||
{
|
||||
TraceSettings oldSettings = new TraceSettings(traceSettings);
|
||||
|
|
@ -39,9 +25,7 @@ public class TraceOutput implements IOutput
|
|||
|
||||
if ((oldSettings.isEntryExitTraceEnabled() != traceSettings.isEntryExitTraceEnabled()) ||
|
||||
(oldSettings.isBranchTraceEnabled() != traceSettings.isBranchTraceEnabled()) ||
|
||||
(oldSettings.isArgTraceEnabled() != traceSettings.isArgTraceEnabled()) ||
|
||||
(oldSettings.isStdoutTraceOutputEnabled() != traceSettings.isStdoutTraceOutputEnabled()) ||
|
||||
(oldSettings.isFileTraceOutputEnabled() != traceSettings.isFileTraceOutputEnabled()))
|
||||
(oldSettings.isArgTraceEnabled() != traceSettings.isArgTraceEnabled()))
|
||||
{
|
||||
System.out.println("## Trace Settings Changed");
|
||||
}
|
||||
|
|
@ -49,102 +33,21 @@ public class TraceOutput implements IOutput
|
|||
entryExitTrace = traceSettings.isEntryExitTraceEnabled();
|
||||
branchTrace = traceSettings.isBranchTraceEnabled();
|
||||
argTrace = traceSettings.isArgTraceEnabled();
|
||||
stdoutTrace = traceSettings.isStdoutTraceOutputEnabled();
|
||||
fileoutTrace = traceSettings.isFileTraceOutputEnabled();
|
||||
|
||||
if (traceSettings.networkTraceOutputRequested)
|
||||
{
|
||||
System.out.println("## Network Trace Requested");
|
||||
ServerSocket networkSocket;
|
||||
try
|
||||
{
|
||||
networkSocket = new ServerSocket(0);
|
||||
NetworkTraceSenderThread traceThread = new NetworkTraceSenderThread(networkSocket);
|
||||
|
||||
traceThreads.put(traceThread, new Object());
|
||||
|
||||
traceThread.start(traceThreads.keySet());
|
||||
traceSettings.networkTraceOutputRequested = false;
|
||||
return Integer.toString(networkSocket.getLocalPort());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Do nothing
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String,String> getSettingsMap()
|
||||
{
|
||||
return traceSettings.getSettingsMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write trace output
|
||||
*
|
||||
* @param xiTrace
|
||||
*/
|
||||
private void writeTrace(String xiTrace)
|
||||
{
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat();
|
||||
long threadID = Thread.currentThread().getId();
|
||||
String traceString = "[" + dateFormat.format(new Date()) + "]:[" +
|
||||
threadID + "]:" + xiTrace;
|
||||
if (stdoutTrace)
|
||||
{
|
||||
System.out.println(traceString);
|
||||
}
|
||||
|
||||
if (fileoutTrace)
|
||||
{
|
||||
writeFileTrace(traceString);
|
||||
}
|
||||
|
||||
Set<NetworkTraceSenderThread> networkThreads = traceThreads.keySet();
|
||||
if (networkThreads.size() > 0)
|
||||
{
|
||||
for (NetworkTraceSenderThread thread : networkThreads)
|
||||
{
|
||||
thread.queueTrace(traceString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void writeFileTrace(String traceString)
|
||||
{
|
||||
PrintWriter outputWriter;
|
||||
if (file1Active)
|
||||
{
|
||||
outputWriter = traceSettings.getFile1TraceWriter();
|
||||
}
|
||||
else
|
||||
{
|
||||
outputWriter = traceSettings.getFile2TraceWriter();
|
||||
}
|
||||
outputWriter.println(traceString);
|
||||
outputWriter.flush();
|
||||
|
||||
// Switch trace files if necessary
|
||||
writtenChars += traceString.length();
|
||||
if (writtenChars > MAX_CHARS_PER_FILE)
|
||||
{
|
||||
writtenChars = 0;
|
||||
traceSettings.resetTraceFiles(file1Active, !file1Active);
|
||||
file1Active = !file1Active;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void arg(String className, String methodName, byte byteArg)
|
||||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: " + byteArg);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: " + byteArg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -152,7 +55,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: "
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: "
|
||||
+ Arrays.toString(byteArrayArg));
|
||||
}
|
||||
}
|
||||
|
|
@ -162,7 +65,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: " + shortArg);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: " + shortArg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +73,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: "
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: "
|
||||
+ Arrays.toString(shortArrayArg));
|
||||
}
|
||||
}
|
||||
|
|
@ -180,7 +83,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: " + intArg);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: " + intArg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -189,7 +92,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: "
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: "
|
||||
+ Arrays.toString(intArrayArg));
|
||||
}
|
||||
}
|
||||
|
|
@ -199,7 +102,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: " + longArg);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: " + longArg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +111,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: "
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: "
|
||||
+ Arrays.toString(longArrayArg));
|
||||
}
|
||||
}
|
||||
|
|
@ -218,7 +121,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: " + floatArg);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: " + floatArg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +130,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: "
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: "
|
||||
+ Arrays.toString(floatArrayArg));
|
||||
}
|
||||
}
|
||||
|
|
@ -237,7 +140,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: " + doubleArg);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: " + doubleArg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -246,7 +149,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: "
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: "
|
||||
+ Arrays.toString(doubleArrayArg));
|
||||
}
|
||||
}
|
||||
|
|
@ -256,7 +159,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: " + boolArg);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: " + boolArg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,7 +168,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: "
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: "
|
||||
+ Arrays.toString(boolArrayArg));
|
||||
}
|
||||
}
|
||||
|
|
@ -275,7 +178,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: " + charArg);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: " + charArg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -284,7 +187,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: "
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: "
|
||||
+ Arrays.toString(charArrayArg));
|
||||
}
|
||||
}
|
||||
|
|
@ -294,7 +197,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: " + objArg);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: " + objArg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -302,7 +205,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (argTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": Arg: "
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": Arg: "
|
||||
+ Arrays.toString(objArrayArg));
|
||||
}
|
||||
}
|
||||
|
|
@ -312,7 +215,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (branchTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": /:" + lineNo);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": /:" + lineNo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +224,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (entryExitTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": {");
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": {");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -330,7 +233,7 @@ public class TraceOutput implements IOutput
|
|||
{
|
||||
if (entryExitTrace)
|
||||
{
|
||||
writeTrace(className + ":" + methodName + ": }:" + lineNo);
|
||||
AgentHelper.writeOutput(className + ":" + methodName + ": }:" + lineNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,32 @@
|
|||
package org.intrace.output.trace;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.intrace.shared.TraceConfigConstants;
|
||||
|
||||
/**
|
||||
* Args Format:
|
||||
* "[arg1[arg2[arg3"
|
||||
*
|
||||
*
|
||||
* where argx is of the form
|
||||
* value-parameter
|
||||
*/
|
||||
public class TraceSettings
|
||||
{
|
||||
private boolean entryExitTraceEnabled = true;
|
||||
private boolean entryExitTraceEnabled = false;
|
||||
private boolean branchTraceEnabled = false;
|
||||
private boolean argTraceEnabled = false;
|
||||
|
||||
private boolean stdoutTraceOutputEnabled = true;
|
||||
private boolean fileTraceOutputEnabled = false;
|
||||
private File file1;
|
||||
private File file2;
|
||||
private PrintWriter file1TraceWriter;
|
||||
private PrintWriter file2TraceWriter;
|
||||
|
||||
public boolean networkTraceOutputRequested = false;
|
||||
|
||||
public TraceSettings(TraceSettings oldSettings)
|
||||
{
|
||||
entryExitTraceEnabled = oldSettings.entryExitTraceEnabled;
|
||||
branchTraceEnabled = oldSettings.branchTraceEnabled;
|
||||
argTraceEnabled = oldSettings.argTraceEnabled;
|
||||
|
||||
stdoutTraceOutputEnabled = oldSettings.stdoutTraceOutputEnabled;
|
||||
fileTraceOutputEnabled = oldSettings.fileTraceOutputEnabled;
|
||||
}
|
||||
|
||||
|
||||
public TraceSettings(String args)
|
||||
{
|
||||
file1 = new File("trc1.txt");
|
||||
file2 = new File("trc2.txt");
|
||||
resetTraceFiles(true, true);
|
||||
{
|
||||
parseArgs(args);
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +38,7 @@ public class TraceSettings
|
|||
parseArg(seperateArgs[ii].toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void parseArg(String arg)
|
||||
{
|
||||
if (arg.equals("trace-ee-false"))
|
||||
|
|
@ -82,61 +65,8 @@ public class TraceSettings
|
|||
{
|
||||
argTraceEnabled = false;
|
||||
}
|
||||
else if (arg.equals("trace-stdout-true"))
|
||||
{
|
||||
stdoutTraceOutputEnabled = true;
|
||||
}
|
||||
else if (arg.equals("trace-stdout-false"))
|
||||
{
|
||||
stdoutTraceOutputEnabled = false;
|
||||
}
|
||||
else if (arg.equals("trace-file-true"))
|
||||
{
|
||||
fileTraceOutputEnabled = true;
|
||||
}
|
||||
else if (arg.equals("trace-file-false"))
|
||||
{
|
||||
fileTraceOutputEnabled = false;
|
||||
}
|
||||
else if (arg.startsWith("trace-file1-"))
|
||||
{
|
||||
String file1Name = arg.replace("trace-file1-", "");
|
||||
file1 = new File(file1Name);
|
||||
resetTraceFiles(true, false);
|
||||
}
|
||||
else if (arg.startsWith("trace-file2-"))
|
||||
{
|
||||
String file2Name = arg.replace("trace-file2-", "");
|
||||
file2 = new File(file2Name);
|
||||
resetTraceFiles(false, true);
|
||||
}
|
||||
else if (arg.equals("trace-network"))
|
||||
{
|
||||
networkTraceOutputRequested = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void resetTraceFiles(boolean resetFile1, boolean resetFile2)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (resetFile1)
|
||||
{
|
||||
file1.delete();
|
||||
file1TraceWriter = new PrintWriter(new FileWriter(file1));
|
||||
}
|
||||
if (resetFile2)
|
||||
{
|
||||
file2.delete();
|
||||
file2TraceWriter = new PrintWriter(new FileWriter(file2));
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// Throw away
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isEntryExitTraceEnabled()
|
||||
{
|
||||
return entryExitTraceEnabled;
|
||||
|
|
@ -152,34 +82,12 @@ public class TraceSettings
|
|||
return argTraceEnabled;
|
||||
}
|
||||
|
||||
public boolean isStdoutTraceOutputEnabled()
|
||||
{
|
||||
return stdoutTraceOutputEnabled;
|
||||
}
|
||||
|
||||
public boolean isFileTraceOutputEnabled()
|
||||
{
|
||||
return fileTraceOutputEnabled;
|
||||
}
|
||||
|
||||
public PrintWriter getFile1TraceWriter()
|
||||
{
|
||||
return file1TraceWriter;
|
||||
}
|
||||
|
||||
public PrintWriter getFile2TraceWriter()
|
||||
{
|
||||
return file2TraceWriter;
|
||||
}
|
||||
|
||||
public Map<String,String> getSettingsMap()
|
||||
{
|
||||
Map<String,String> settingsMap = new HashMap<String, String>();
|
||||
settingsMap.put(TraceConfigConstants.ENTRY_EXIT, Boolean.toString(entryExitTraceEnabled));
|
||||
settingsMap.put(TraceConfigConstants.BRANCH, Boolean.toString(branchTraceEnabled));
|
||||
settingsMap.put(TraceConfigConstants.ARG, Boolean.toString(argTraceEnabled));
|
||||
settingsMap.put(TraceConfigConstants.STD_OUT, Boolean.toString(stdoutTraceOutputEnabled));
|
||||
settingsMap.put(TraceConfigConstants.FILE_OUT, Boolean.toString(fileTraceOutputEnabled));
|
||||
return settingsMap;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package org.intrace.shared;
|
||||
|
||||
public class AgentConfigConstants
|
||||
{
|
||||
public static final String MAP_ID = "SETTINGS";
|
||||
public static final String CLASS_REGEX = "AGENT_CLASS_REGEX";
|
||||
public static final String TRACING_ENABLED = "AGENT_TRACING_ENABLED";
|
||||
public static final String SAVE_TRACED_CLASSFILES = "AGENT_SAVE_TRACED_CLASSFILES";
|
||||
public static final String VERBOSE_MODE = "AGENT_VERBOSE_MODE";
|
||||
public static final String ALLOW_JARS_TO_BE_TRACED = "AGENT_LLOW_JARS_TO_BE_TRACED";
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package org.intrace.shared;
|
||||
|
||||
public class CallersConfigConstants
|
||||
{
|
||||
public static final String MAP_ID = "CALLERS";
|
||||
public static final String CALLERS_ENABLED = "CALLERS_ENABLED";
|
||||
public static final String PATTERN = "CALLERS_PATTERN";
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package org.intrace.shared;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class CallersTree
|
||||
{
|
||||
public CallersTree(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
public final String name;
|
||||
public final Collection<CallersTree> callersChildren = new ConcurrentLinkedQueue<CallersTree>();
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package org.intrace.shared;
|
||||
|
||||
public class OutputConfigConstants
|
||||
{
|
||||
public static final String STD_OUT = "TRACE_STD_OUT";
|
||||
public static final String FILE_OUT = "TRACE_FILE_OUT";
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package org.intrace.shared;
|
||||
|
||||
public class TraceConfigConstants
|
||||
{
|
||||
public static final String ENTRY_EXIT = "TRACE_ENTRY_EXIT";
|
||||
public static final String BRANCH = "TRACE_BRANCH";
|
||||
public static final String ARG = "TRACE_ARG";
|
||||
}
|
||||
Loading…
Reference in New Issue