Search in sources :

Example 1 with TraceContext

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

MissingDataException (com.ibm.jvm.trace.format.api.MissingDataException)1 TraceContext (com.ibm.jvm.trace.format.api.TraceContext)1 TracePoint (com.ibm.jvm.trace.format.api.TracePoint)1 TracePointImpl (com.ibm.jvm.trace.format.api.TracePointImpl)1 TraceThread (com.ibm.jvm.trace.format.api.TraceThread)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 BufferUnderflowException (java.nio.BufferUnderflowException)1 ByteBuffer (java.nio.ByteBuffer)1 Iterator (java.util.Iterator)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1