info.mikaelsvensson.devtools.analysis.db2eventlog.Db2EventLogReportGenerator.java Source code

Java tutorial

Introduction

Here is the source code for info.mikaelsvensson.devtools.analysis.db2eventlog.Db2EventLogReportGenerator.java

Source

/*
 * Copyright 2014 Mikael Svensson
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package info.mikaelsvensson.devtools.analysis.db2eventlog;

import info.mikaelsvensson.devtools.analysis.shared.ReportGenerator;
import info.mikaelsvensson.devtools.analysis.shared.reportprinter.ReportPrinter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableLong;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
import java.text.NumberFormat;
import java.util.*;

/**
 * Summarizes DB2 event log generated by the <tt>db2evmon</tt> utility.
 * <p/>
 * Example:
 * java info.mikaelsvensson.devtools.analysis.db2eventlog.Db2EventLogReport C:\TEMP\db2evmon-output.txt
 */
public class Db2EventLogReportGenerator implements ReportGenerator {
    private static final int MILLION = 1000000;
    private static final String LINE_FORMAT = "%10s %10s %6s %15s %15s %15s %10s %-60s %8s %s%n";
    private Db2EventLogReport _report = null;

    public Db2EventLogReportGenerator(Db2EventLogReport report) {
        _report = report;
    }

    private static void printHeader(PrintStream stream, String header) {
        stream.println();
        stream.println(header);
        stream.println(StringUtils.repeat('-', header.length()));
        stream.println();
    }

    private static void sortQueryDataByTime(List<QueryStatistics> data) {
        Collections.sort(data, QueryStatistics.TOTAL_TIME_COMPARATOR);
    }

    private static void sortQueryDataBySamples(List<QueryStatistics> data) {
        Collections.sort(data, QueryStatistics.CALL_COUNT_COMPARATOR);
    }

    private static void printQueryData(List<QueryStatistics> data, PrintStream stream) {
        stream.format(LINE_FORMAT, "Samples", "Time", "Time", "Rows Read", "Rows Written", "Fetch Count", "Sorts",
                "Timing Details", "Query Id", "Query String");
        stream.format(LINE_FORMAT, "-------", "----", "----", "---------", "------------", "-----------", "-----",
                "--------------", "--------", "------------");
        long overallTime = 0;
        Date lastTimeStamp = null;
        Date firstTimeStamp = null;
        for (QueryStatistics queryStatistics : data) {
            overallTime += queryStatistics.getAccumulatedExecutionTime();
            if (lastTimeStamp == null || queryStatistics.getLastTimeStamp().after(lastTimeStamp)) {
                lastTimeStamp = queryStatistics.getLastTimeStamp();
            }
            if (firstTimeStamp == null || queryStatistics.getFirstTimeStamp().before(firstTimeStamp)) {
                firstTimeStamp = queryStatistics.getFirstTimeStamp();
            }
        }
        int overallSamples = 0;
        for (QueryStatistics queryStatistics : data) {
            long time = queryStatistics.getAccumulatedExecutionTime();
            final int sampleCount = queryStatistics.getTotalSamples();
            final int numberOfOperations = queryStatistics.getOperationsTime().size();
            if (sampleCount % numberOfOperations != 0) {
                System.err.println(
                        "Number of samples is not divisible by the number of different operations (see the Timing Details column). Problematic query: "
                                + queryStatistics.getQuery());
            }
            final int correctedSampleCount = sampleCount / numberOfOperations;
            overallSamples += correctedSampleCount;
            stream.format(LINE_FORMAT, correctedSampleCount, toDisplayTime(time),
                    NumberFormat.getPercentInstance().format(1.0 * time / overallTime),
                    queryStatistics.getRowsRead(), queryStatistics.getRowsWritten(),
                    queryStatistics.getFetchCount(), queryStatistics.getSorts(),
                    toString(queryStatistics.getOperationsTime()), queryStatistics.getId(),
                    queryStatistics.getQuery());
        }
        stream.format(LINE_FORMAT, "-------", "----", "----", "---------", "------------", "-----------", "-----",
                "--------------", "--------", "------------");
        stream.format("%10d %10s%n", overallSamples, toDisplayTime(overallTime));
        stream.println();
        stream.format("Accumulated execution time according to Elapsed Execution Time values: %s%n",
                toDisplayTime(overallTime));
        stream.format("Period of time when logging was enabled according to time stamps:      %s%n",
                toDisplayTime((lastTimeStamp.getTime() - firstTimeStamp.getTime()) * 1000));
    }

    private static String toDisplayTime(long microSeconds) {
        return Math.round(1.0 * microSeconds / MILLION) + " s";
    }

    private static String toString(Map<String, MutableLong> operationsTime) {
        String str = null;
        for (Map.Entry<String, MutableLong> entry : operationsTime.entrySet()) {
            str = (str == null ? "" : str + ", ") + entry.getKey() + ": "
                    + toDisplayTime(entry.getValue().longValue());
        }
        return str;
    }

    @Override
    public void generateReport(File outputFile, ReportPrinter reportPrinter) throws IOException {
        PrintStream stream = new PrintStream(outputFile);

        printHeader(stream,
                "Report for " + _report.getStartTime().toString() + " to " + _report.getStopTime().toString() + " ("
                        + (_report.getStopTime().getTime() - _report.getStartTime().getTime()) / (1000 * 60)
                        + " minutes)");

        List<QueryStatistics> values = new ArrayList<QueryStatistics>(_report.getRecords().values());

        printHeader(stream, "Queries Sorted by Total Execution Time (only top 10 queries shown)");
        sortQueryDataByTime(values);
        printQueryData(values.subList(0, Math.min(10, values.size())), stream);

        printHeader(stream, "Queries Sorted by Total Number of Calls (all queries shown)");
        sortQueryDataBySamples(values);
        printQueryData(values, stream);

        stream.close();
    }

    @Override
    public void generateSamplesCSV(File file) throws FileNotFoundException {
        throw new UnsupportedOperationException();
    }
}