Search in sources :

Example 1 with TracePointImpl

use of com.ibm.jvm.trace.format.api.TracePointImpl 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 TracePointImpl

use of com.ibm.jvm.trace.format.api.TracePointImpl 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)

Aggregations

TracePoint (com.ibm.jvm.trace.format.api.TracePoint)2 TracePointImpl (com.ibm.jvm.trace.format.api.TracePointImpl)2 TraceThread (com.ibm.jvm.trace.format.api.TraceThread)2 BufferUnderflowException (java.nio.BufferUnderflowException)2 MissingDataException (com.ibm.jvm.trace.format.api.MissingDataException)1 TraceContext (com.ibm.jvm.trace.format.api.TraceContext)1 File (java.io.File)1 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 PrintStream (java.io.PrintStream)1 PrintWriter (java.io.PrintWriter)1 RandomAccessFile (java.io.RandomAccessFile)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 ByteBuffer (java.nio.ByteBuffer)1 Iterator (java.util.Iterator)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1