use of com.ibm.jvm.trace.format.api.TracePoint in project openj9 by eclipse.
the class SnapFormatCommand method printTracePoints.
private int printTracePoints(PrintStream traceOut, Iterator<TracePoint> tpIterator, TraceFilterExpression specFilter) {
int tpCount = 0;
TraceThread thread = null;
while (tpIterator.hasNext()) {
TracePoint tp = tpIterator.next();
TracePointImpl tracepoint = null;
if (tp instanceof TracePointImpl) {
tracepoint = (TracePointImpl) tp;
}
if ((tracepoint != null) && ((specFilter == null) || specFilter.matches(tracepoint))) {
TraceThread current = tracepoint.getThread();
String component = tracepoint.getComponentName();
int tpID = tracepoint.getID();
String container = tracepoint.getContainerComponent();
tpCount++;
String parameters = "";
try {
parameters = tracepoint.getFormattedParameters();
if (parameters == null || parameters.length() == 0) {
traceContext.error(traceContext, "null parameter data for trace point " + component + "." + tpID);
}
} catch (BufferUnderflowException e) {
/* This may be thrown, but there's essentially nothing we can do about it at this level so
* just report it
*/
traceContext.error(traceContext, "Underflow accessing parameter data for trace point " + component + "." + tpID);
}
StringBuilder formatted = new StringBuilder();
formatted.append(tracepoint.getFormattedTime());
/* append thread id */
formatted.append(" ").append((current != thread ? "*" : " "));
formatted.append(String.format("0x%X", current.getThreadID()));
formatted.append(" ");
/* append component and padding */
StringBuilder fullTracepointID = new StringBuilder(component);
fullTracepointID.append(container != null ? "(" + container + ")" : "").append(".").append(tpID);
formatted.append(String.format("%-20s", fullTracepointID.toString()));
formatted.append(" ");
formatted.append(tracepoint.getType());
formatted.append(parameters.length() > 0 ? ((parameters.charAt(0) == '*' ? " " : "") + parameters) : "");
thread = current;
traceOut.println(formatted.toString());
}
}
return tpCount;
}
use of com.ibm.jvm.trace.format.api.TracePoint in project openj9 by eclipse.
the class ProgramOption method main.
/**
* @param args
*/
public static void main(String[] args) throws Exception {
/* Add the option parsers we want to provide */
ProgramOption.addOption(InputFile.class);
ProgramOption.addOption(OutputFile.class);
ProgramOption.addOption(MessageFile.class);
ProgramOption.addOption(FormatTimestamp.class);
ProgramOption.addOption(Indent.class);
ProgramOption.addOption(Summary.class);
ProgramOption.addOption(Threads.class);
ProgramOption.addOption(Timezone.class);
ProgramOption.addOption(Verbose.class);
ProgramOption.addOption(Debug.class);
ProgramOption.addOption(Statistics.class);
/* The trace context holds the configuration and state for the parsing */
TraceContext context;
/* Process the command line options and populate any unspecified options with default values */
try {
for (int i = 0; i < args.length; i++) {
ProgramOption.addArgument(args[i]);
}
ProgramOption.applyDefaults();
} catch (IllegalArgumentException e) {
System.err.println(e.getMessage());
return;
}
/*
* At this point we have valid data for all command line options so get on with the parsing
*/
/* Get the input files to process */
List inputFiles = (List) ProgramOption.getValue("input_file");
List messageFiles = (List) ProgramOption.getValue("datfile");
List threads = (List) ProgramOption.getValue("threads");
Integer timezone = (Integer) ProgramOption.getValue("timezone");
Boolean formatTime = (Boolean) ProgramOption.getValue("format_time");
Boolean indenting = (Boolean) ProgramOption.getValue("indent");
Boolean summary = (Boolean) ProgramOption.getValue("summary");
Boolean verbose = (Boolean) ProgramOption.getValue("verbose");
Integer debugLevel = (Integer) ProgramOption.getValue("debug");
Boolean statistics = (Boolean) ProgramOption.getValue("statistics");
/* Parse the header on the first file */
int blockSize = 4000;
PrintStream error = null;
PrintStream warning = null;
PrintStream debug = null;
if (debugLevel.intValue() > 0) {
debug = System.err;
}
try {
while (true) {
try {
ByteBuffer data;
data = ((RandomAccessFile) inputFiles.get(0)).getChannel().map(FileChannel.MapMode.READ_ONLY, 0, blockSize);
context = TraceContext.getContext(data, (File) messageFiles.get(0), System.out, warning, error, debug);
break;
} catch (BufferUnderflowException e) {
blockSize *= 2;
}
}
} catch (IOException e) {
/* could be many things, one is a file shorter than blockSize so try a different method */
try {
long length = ((RandomAccessFile) inputFiles.get(0)).length();
if (length > 0) {
byte[] header = new byte[(int) length];
((RandomAccessFile) inputFiles.get(0)).seek(0);
int i = ((RandomAccessFile) inputFiles.get(0)).read(header);
if (i == length && length < blockSize) {
context = TraceContext.getContext(header, header.length, (File) messageFiles.get(0), System.out, warning, error, debug);
} else {
throw new Exception("received premature end of file: " + e.getMessage());
}
} else {
throw new Exception("empty trace file");
}
} catch (Exception f) {
/* this wasn't due to filesize < blocksize so print the exception message and exit */
System.err.println("Unable to read trace header from file: " + f.getMessage());
System.err.println("Please check that the input file is a binary trace file");
return;
}
} catch (IllegalArgumentException e) {
System.err.println("Problem reading the trace file header: " + e.getMessage());
System.err.println("Please check that that the input file is a binary trace file");
return;
}
if (verbose.booleanValue() || debugLevel.intValue() > 0) {
/* we don't set these in the constructor otherwise we see error messages during the retry logic if the block
* size estimate is too small */
context.setErrorStream(System.err);
context.setWarningStream(System.err);
}
context.setDebugLevel(debugLevel.intValue());
/* set up the thread filters */
Iterator itr = threads.iterator();
while (itr.hasNext()) {
Long id = (Long) itr.next();
context.addThreadToFilter(id);
}
context.setTimeZoneOffset(timezone.intValue());
/* add any remaining dat files */
for (int i = 1; i < messageFiles.size(); i++) {
File file = (File) messageFiles.get(i);
try {
context.addMessageData(file);
} catch (IOException e) {
// Problem reading one of the trace format .dat files, issue message and exit
System.err.println("Unable to process trace format data file: " + file.getAbsolutePath() + " (" + e.getMessage() + ")");
return;
}
}
/* Set the output file */
PrintWriter output = (PrintWriter) ProgramOption.getValue("output_file");
/* read in the blocks from the various files and sort them */
long recordsInData = 0;
long lostCountByException = 0;
long start = System.currentTimeMillis();
long end = 0;
long startBlock = start;
long recordsProcessed = 0;
long totalBytes = 0;
/* loop over the generational files and add the blocks to the context */
for (int i = 0; i < inputFiles.size(); i++) {
long offset = context.getHeaderSize();
long recordSize = context.getRecordSize();
RandomAccessFile traceFile = (RandomAccessFile) inputFiles.get(i);
long length = traceFile.length();
if ((length - context.getHeaderSize()) % recordSize != 0) {
context.warning(context, "The body of the trace file is not a multiple of the record size, file either truncated or corrupt");
}
while (offset < length) {
try {
TraceThread thread = context.addData(traceFile, offset);
indentMap.put(thread, "");
} catch (IllegalArgumentException e) {
context.error(context, "Bad block of trace data in input file at offset " + offset + ": " + e.getMessage());
}
offset += recordSize;
totalBytes += recordSize;
recordsInData++;
}
}
/* output the summary information */
output.println(context.summary());
if (summary.booleanValue() && !statistics.booleanValue()) {
/* we've requested only the summary so exit here */
output.close();
return;
}
if (!summary.booleanValue()) {
/* output the section header line and the column headings for the trace point data section */
output.println(" Trace Formatted Data " + System.getProperty("line.separator"));
String columnHeader;
if (timezone.intValue() == 0) {
columnHeader = "Time (UTC) ";
} else {
/* user specified a timezone offset, show that in the timestamp column header */
if (timezone.intValue() > 0) {
columnHeader = "Time (UTC +";
} else {
columnHeader = "Time (UTC -";
}
columnHeader += Math.abs(timezone.intValue() / 60) + ":" + Math.abs(timezone.intValue() % 60) + ") ";
}
if (context.getPointerSize() == 4) {
columnHeader += "Thread ID ";
} else {
columnHeader += "Thread ID ";
}
columnHeader += " Tracepoint ID Type Tracepoint Data";
output.println(columnHeader);
}
/* start reading tracepoints */
itr = context.getTracepoints();
String totalMbytes = (float) totalBytes / (float) (1024 * 1024) + "Mb";
context.message(context, "Processing " + totalMbytes + " of binary trace data");
TraceThread thread = null;
String indent = "";
while (itr.hasNext()) {
TracePointImpl tracepoint;
try {
tracepoint = (TracePointImpl) itr.next();
} catch (MissingDataException e) {
lostCountByException += e.getMissingBytes() / context.getRecordSize();
continue;
}
/* If we've only been asked for the summary we don't format the trace */
if (!summary.booleanValue()) {
TraceThread current = tracepoint.getThread();
String component = tracepoint.getComponentName();
int tpID = tracepoint.getID();
String container = tracepoint.getContainerComponent();
String parameters = "";
try {
parameters = tracepoint.getFormattedParameters();
if (parameters == null || parameters.length() == 0) {
context.error(context, "null parameter data for trace point " + component + "." + tpID);
}
} catch (BufferUnderflowException e) {
/* This may be thrown, but there's essentially nothing we can do about it at this level so
* just report it
*/
context.error(context, "Underflow accessing parameter data for trace point " + component + "." + tpID);
}
StringBuilder formatted = new StringBuilder();
if (formatTime.booleanValue()) {
formatted.append(tracepoint.getFormattedTime());
} else {
formatted.append(tracepoint.getRawTime());
}
/* append thread id */
formatted.append(" ").append((current != thread ? "*" : " "));
formatted.append(context.formatPointer(current.getThreadID()));
formatted.append(" ");
/* append component and padding - add container if this is a sub component.
* e.g j9codertvm(j9jit).91 vs j9jit.18 */
String fullTracepointID = String.format((container != null ? "%s(%s).%d" : "%1$s.%3$d"), component, container, tpID);
/* Left justify but include a space in the formatting as a column separator in case of very long component id's. */
formatted.append(String.format("%-19s ", fullTracepointID));
formatted.append(tracepoint.getType());
if (indenting.booleanValue()) {
indent = indentMap.get(current).toString();
/* we remove the indent before appending for exit */
if (tracepoint.getTypeAsInt() == TracePoint.EXIT_TYPE || tracepoint.getTypeAsInt() == TracePoint.EXIT_EXCPT_TYPE) {
try {
indent = indent.substring(2);
indentMap.put(current, indent);
} catch (IndexOutOfBoundsException e) {
indent = "";
indentMap.put(current, "");
}
}
formatted.append(indent);
}
formatted.append(parameters.length() > 0 ? ((parameters.charAt(0) == '*' ? " " : "") + parameters) : "");
if (indenting.booleanValue()) {
/* juggle the indent for the thread */
if (tracepoint.getTypeAsInt() == TracePoint.ENTRY_TYPE || tracepoint.getTypeAsInt() == TracePoint.ENTRY_EXCPT_TYPE) {
indent = indent + " ";
indentMap.put(current, indent);
}
}
if (debugLevel > 0) {
formatted.append(" [" + ((TracePointImpl) tracepoint).getDebugInfo() + "]");
}
thread = current;
output.println(formatted.toString());
}
/* print percentage */
if (context.getTotalRecords() != recordsProcessed) {
recordsProcessed = context.getTotalRecords();
float processedMbytes = ((float) (context.getTotalRecords() * context.getRecordSize())) / (1024 * 1024);
if (processedMbytes % 10 == 0) {
int percent = (int) ((processedMbytes * 100) / (totalBytes / (1024 * 1024)));
if (verbose.booleanValue()) {
end = System.currentTimeMillis();
float MbpsBlock = (float) 10.0 / (float) ((end - startBlock) / 1000.0);
float Mbps = (float) (processedMbytes) / (float) (((float) (end - start) / 1000.0));
startBlock = System.currentTimeMillis();
context.message(context, "Processed " + processedMbytes + "Mb (" + percent + "%), burst speed: " + MbpsBlock + "Mb/s, average: " + Mbps + "Mb/s");
} else {
context.message(context, "Processed " + processedMbytes + "Mb (" + percent + "%)");
}
}
}
}
if (lostCountByException > 0) {
context.warning(context, lostCountByException + " records were discarded during trace generation");
}
output.close();
context.message(context, "Completed processing of " + context.getTotalTracePoints() + " tracepoints with " + context.getWarningCount() + " warnings and " + context.getErrorCount() + " errors");
if (verbose.booleanValue()) {
end = System.currentTimeMillis();
float Mbps = (float) (recordsInData * context.getRecordSize()) / (float) (((float) (end - start) / 1000) * (1024 * 1024));
context.message(context, "Total processing time " + (end - start) + "ms (" + Mbps + "Mb/s)");
}
if (statistics) {
context.message(context, context.statistics());
}
}
use of com.ibm.jvm.trace.format.api.TracePoint in project openj9 by eclipse.
the class SnapFormatCommand method run.
/**
* Options should be:
* -f ouputFile
* -t vmthread
* -d .dat file path
*/
public void run(String command, String[] args, Context context, PrintStream out) throws DDRInteractiveCommandException {
String fileName = null;
String userDatPath = null;
String userThreadId = null;
String messageFilePath = null;
TraceFilterExpression specFilter = null;
if (args.length == 0) {
// Write formatted trace to the console.
fileName = null;
} else if (args.length == 1) {
fileName = args[0];
} else {
/* Walk the arguments and look for flag/value pairs. */
for (int i = 0; i < args.length - 1; ) {
String flag = args[i++];
String value = args[i++];
if ("-f".equals(flag)) {
fileName = value;
} else if ("-d".equals(flag)) {
userDatPath = value;
} else if ("-t".equals(flag)) {
userThreadId = value;
outputHeader = false;
} else if ("-s".equals(flag)) {
specFilter = TraceFilterExpression.parseExpression(value);
outputHeader = false;
}
}
}
/* Look for message files, search order is:
* - User specified location to this command.
* - as resources located under same class loader as TraceContext
* - current working directory
* - jre/lib for the current jre
*/
boolean foundDatFiles = false;
if (userDatPath != null) {
int i = 0;
for (String name : MESSAGEFILENAMES) {
File f = new File(userDatPath + File.separator + name);
if (!f.exists()) {
out.printf("Error locating .dat file %s on user path %s\n", name, userDatPath);
return;
} else {
try {
messageFiles[i++] = new FileInputStream(f);
foundDatFiles = true;
} catch (FileNotFoundException e) {
// We've done f.exists(), this should be fine.
// foundDatFiles will be false if not.
}
}
}
} else {
int i = 0;
String[] messageFileStrings = new String[MESSAGEFILENAMES.length];
for (String name : MESSAGEFILENAMES) {
InputStream s = TraceContext.class.getResourceAsStream('/' + name);
if (null != s) {
messageFileStrings[i] = TraceContext.class.getResource('/' + name).toString();
messageFiles[i++] = s;
foundDatFiles = true;
}
}
if (foundDatFiles) {
out.printf("Formatting trace using format dat files from %s and %s\n", messageFileStrings[0], messageFileStrings[1]);
} else {
for (String path : DEFAULTMESSAGEFILEPATHS) {
for (String name : MESSAGEFILENAMES) {
File f = new File(path + File.separator + name);
if (f.exists()) {
try {
messageFiles[i++] = new FileInputStream(f);
foundDatFiles = true;
} catch (FileNotFoundException e) {
// We've done f.exists(), this should be fine.
// foundDatFiles will be false if not.
}
}
}
if (foundDatFiles) {
messageFilePath = path;
out.printf("Formatting trace using format dat files from %s and %s from %s\n", MESSAGEFILENAMES[0], MESSAGEFILENAMES[1], messageFilePath);
break;
}
}
}
if (!foundDatFiles) {
out.printf("Unable to find %s and %s in %s or %s\n", MESSAGEFILENAMES[0], MESSAGEFILENAMES[1], DEFAULTMESSAGEFILEPATHS[0], DEFAULTMESSAGEFILEPATHS[1]);
return;
}
}
if (outputHeader) {
extractTraceData(context, out);
} else {
extractTraceData(context, dummyOut);
}
if (traceContext == null) {
out.println("Unable to create trace context, command failed.");
return;
}
long threadId = 0;
if (userThreadId != null) {
boolean is64BitPlatform = (context.process.bytesPerPointer() == 8) ? true : false;
threadId = CommandUtils.parsePointer(userThreadId, is64BitPlatform);
}
/* Create the stream to write the trace to.
* The specified output file or "out" if we
* are writing to the console.
* (Do this last so we have less cases where we
* need to exit for an error and close the printstream.)
*/
PrintStream traceOut = out;
PrintStream filePrintStream = null;
if (fileName != null) {
try {
filePrintStream = new PrintStream(fileName);
traceOut = filePrintStream;
} catch (FileNotFoundException e) {
out.printf("Unable to write formatted trace to file %s\n", fileName);
}
}
if (outputHeader) {
traceOut.println(traceContext.summary());
}
try {
Iterator<TracePoint> tpIterator = null;
if (userThreadId != null) {
Iterator<TraceThread> threadsIterator = (Iterator<TraceThread>) traceContext.getThreads();
boolean foundThread = false;
while (threadsIterator.hasNext()) {
TraceThread thread = threadsIterator.next();
if (thread.getThreadID() == threadId) {
foundThread = true;
tpIterator = (Iterator<TracePoint>) thread.getIterator();
}
}
if (!foundThread) {
out.printf("Unable to find thread %s in trace data\n", userThreadId);
}
} else {
tpIterator = (Iterator<TracePoint>) traceContext.getTracepoints();
}
if (tpIterator != null) {
int tpCount = printTracePoints(traceOut, tpIterator, specFilter);
out.printf("Completed processing of %d tracepoints with %d warnings and %d errors\n", traceContext.getTotalTracePoints(), traceContext.getWarningCount(), traceContext.getErrorCount());
}
} catch (Exception e) {
e.printStackTrace();
}
if (filePrintStream != null) {
out.println("Snap trace written to: " + fileName);
filePrintStream.close();
}
}
Aggregations