Search in sources :

Example 1 with TracePoint

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;
}
Also used : TraceThread(com.ibm.jvm.trace.format.api.TraceThread) TracePoint(com.ibm.jvm.trace.format.api.TracePoint) TracePointImpl(com.ibm.jvm.trace.format.api.TracePointImpl) TracePoint(com.ibm.jvm.trace.format.api.TracePoint) BufferUnderflowException(java.nio.BufferUnderflowException)

Example 2 with TracePoint

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());
    }
}
Also used : PrintStream(java.io.PrintStream) IOException(java.io.IOException) TracePointImpl(com.ibm.jvm.trace.format.api.TracePointImpl) ByteBuffer(java.nio.ByteBuffer) MissingDataException(com.ibm.jvm.trace.format.api.MissingDataException) TracePoint(com.ibm.jvm.trace.format.api.TracePoint) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) BufferUnderflowException(java.nio.BufferUnderflowException) MissingDataException(com.ibm.jvm.trace.format.api.MissingDataException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) TraceThread(com.ibm.jvm.trace.format.api.TraceThread) RandomAccessFile(java.io.RandomAccessFile) Iterator(java.util.Iterator) TraceContext(com.ibm.jvm.trace.format.api.TraceContext) List(java.util.List) LinkedList(java.util.LinkedList) RandomAccessFile(java.io.RandomAccessFile) File(java.io.File) BufferUnderflowException(java.nio.BufferUnderflowException) PrintWriter(java.io.PrintWriter)

Example 3 with TracePoint

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();
    }
}
Also used : PrintStream(java.io.PrintStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) FileNotFoundException(java.io.FileNotFoundException) TracePoint(com.ibm.jvm.trace.format.api.TracePoint) TracePoint(com.ibm.jvm.trace.format.api.TracePoint) FileInputStream(java.io.FileInputStream) DDRInteractiveCommandException(com.ibm.j9ddr.tools.ddrinteractive.DDRInteractiveCommandException) IOException(java.io.IOException) CorruptDataException(com.ibm.j9ddr.CorruptDataException) FileNotFoundException(java.io.FileNotFoundException) BufferUnderflowException(java.nio.BufferUnderflowException) TraceThread(com.ibm.jvm.trace.format.api.TraceThread) Iterator(java.util.Iterator) File(java.io.File)

Aggregations

TracePoint (com.ibm.jvm.trace.format.api.TracePoint)3 TraceThread (com.ibm.jvm.trace.format.api.TraceThread)3 BufferUnderflowException (java.nio.BufferUnderflowException)3 TracePointImpl (com.ibm.jvm.trace.format.api.TracePointImpl)2 File (java.io.File)2 FileNotFoundException (java.io.FileNotFoundException)2 IOException (java.io.IOException)2 PrintStream (java.io.PrintStream)2 Iterator (java.util.Iterator)2 CorruptDataException (com.ibm.j9ddr.CorruptDataException)1 DDRInteractiveCommandException (com.ibm.j9ddr.tools.ddrinteractive.DDRInteractiveCommandException)1 MissingDataException (com.ibm.jvm.trace.format.api.MissingDataException)1 TraceContext (com.ibm.jvm.trace.format.api.TraceContext)1 FileInputStream (java.io.FileInputStream)1 InputStream (java.io.InputStream)1 PrintWriter (java.io.PrintWriter)1 RandomAccessFile (java.io.RandomAccessFile)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 ByteBuffer (java.nio.ByteBuffer)1 LinkedList (java.util.LinkedList)1