Java tutorial
/* * 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(); } }