From 6133c3f93d2664f8923ec027443041e595eadead Mon Sep 17 00:00:00 2001 From: Klaas Boesche Date: Fri, 9 Oct 2015 13:24:28 +0000 Subject: Add combine option for multiple profile file stats Add the --combine option to produce a single aggregated statistics output for multiple profile files. Outputs neither Skylark histograms nor the task chart. -- MOS_MIGRATED_REVID=105051164 --- .../build/lib/runtime/commands/ProfileCommand.java | 151 ++++++++++++++------- 1 file changed, 100 insertions(+), 51 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib/runtime/commands') diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/ProfileCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/ProfileCommand.java index 30eeb76111..b21d7ca20d 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/commands/ProfileCommand.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/ProfileCommand.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.profiler.ProfilerTask; import com.google.devtools.build.lib.profiler.output.HtmlCreator; import com.google.devtools.build.lib.profiler.output.PhaseText; import com.google.devtools.build.lib.profiler.statistics.CriticalPathStatistics; +import com.google.devtools.build.lib.profiler.statistics.MultiProfileStatistics; import com.google.devtools.build.lib.profiler.statistics.PhaseStatistics; import com.google.devtools.build.lib.profiler.statistics.PhaseSummaryStatistics; import com.google.devtools.build.lib.runtime.BlazeCommand; @@ -42,6 +43,7 @@ import com.google.devtools.common.options.OptionsBase; import com.google.devtools.common.options.OptionsParser; import com.google.devtools.common.options.OptionsProvider; +import java.io.BufferedOutputStream; import java.io.IOException; import java.io.PrintStream; import java.util.EnumMap; @@ -75,6 +77,16 @@ public final class ProfileCommand implements BlazeCommand { ) public boolean chart; + @Option( + name = "combine", + defaultValue = "null", + help = + "If present, the statistics of all given profile files will be combined and output" + + " in text/--html format to the file named in the argument. Does not output HTML" + + " task charts." + ) + public String combine; + @Option(name = "dump", abbrev='d', converter = DumpConverter.class, @@ -178,65 +190,102 @@ public final class ProfileCommand implements BlazeCommand { env.getReporter().handle(Event.warn( null, "This information is intended for consumption by Blaze developers" + " only, and may change at any time. Script against it at your own risk")); - - for (String name : options.getResidue()) { - Path profileFile = runtime.getWorkingDirectory().getRelative(name); - try { - ProfileInfo info = ProfileInfo.loadProfileVerbosely( - profileFile, getInfoListener(env)); - - if (opts.dumpMode == null || !opts.dumpMode.contains("unsorted")) { - ProfileInfo.aggregateProfile(info, getInfoListener(env)); - } - - if (opts.taskTree != null) { - printTaskTree(out, name, info, opts.taskTree, opts.taskTreeThreshold); - continue; - } - - if (opts.dumpMode != null) { - dumpProfile(info, out, opts.dumpMode); - continue; - } - - PhaseSummaryStatistics phaseSummaryStatistics = new PhaseSummaryStatistics(info); - EnumMap phaseStatistics = - new EnumMap<>(ProfilePhase.class); - for (ProfilePhase phase : ProfilePhase.values()) { - phaseStatistics.put( - phase, new PhaseStatistics(phase, info, runtime.getWorkspaceName())); - } - + if (opts.combine != null && opts.dumpMode == null) { + MultiProfileStatistics statistics = + new MultiProfileStatistics( + runtime.getWorkingDirectory(), + runtime.getWorkspaceName(), + options.getResidue(), + getInfoListener(env), + opts.vfsStatsLimit > 0); + Path outputFile = runtime.getWorkingDirectory().getRelative(opts.combine); + try (PrintStream output = + new PrintStream(new BufferedOutputStream(outputFile.getOutputStream()))) { if (opts.html) { - Path htmlFile = - profileFile.getParentDirectory().getChild(profileFile.getBaseName() + ".html"); - - env.getReporter().handle(Event.info("Creating HTML output in " + htmlFile)); - + env.getReporter().handle(Event.info("Creating HTML output in " + outputFile)); HtmlCreator.create( - info, - htmlFile, - phaseSummaryStatistics, - phaseStatistics, - opts.htmlDetails, - opts.htmlPixelsPerSecond, - opts.vfsStatsLimit, - opts.chart, - opts.htmlHistograms); + output, statistics, opts.htmlDetails, opts.htmlPixelsPerSecond, opts.vfsStatsLimit); } else { - CriticalPathStatistics critPathStats = new CriticalPathStatistics(info); + env.getReporter().handle(Event.info("Creating text output in " + outputFile)); new PhaseText( - out, - phaseSummaryStatistics, - phaseStatistics, - Optional.of(critPathStats), - info.getMissingActionsCount(), + output, + statistics.getSummaryStatistics(), + statistics.getSummaryPhaseStatistics(), + Optional.absent(), + statistics.getMissingActionsCount(), opts.vfsStatsLimit) .print(); } } catch (IOException e) { - env.getReporter().handle(Event.error( - null, "Failed to process file " + name + ": " + e.getMessage())); + env + .getReporter() + .handle( + Event.error( + "Failed to write to output file " + outputFile + ":" + e.getMessage())); + } + } else { + for (String name : options.getResidue()) { + Path profileFile = runtime.getWorkingDirectory().getRelative(name); + try { + ProfileInfo info = ProfileInfo.loadProfileVerbosely(profileFile, getInfoListener(env)); + + if (opts.dumpMode == null || !opts.dumpMode.contains("unsorted")) { + ProfileInfo.aggregateProfile(info, getInfoListener(env)); + } + + if (opts.taskTree != null) { + printTaskTree(out, name, info, opts.taskTree, opts.taskTreeThreshold); + continue; + } + + if (opts.dumpMode != null) { + dumpProfile(info, out, opts.dumpMode); + continue; + } + + PhaseSummaryStatistics phaseSummaryStatistics = new PhaseSummaryStatistics(info); + EnumMap phaseStatistics = + new EnumMap<>(ProfilePhase.class); + for (ProfilePhase phase : ProfilePhase.values()) { + phaseStatistics.put( + phase, + new PhaseStatistics( + phase, info, runtime.getWorkspaceName(), opts.vfsStatsLimit > 0)); + } + + if (opts.html) { + Path htmlFile = + profileFile.getParentDirectory().getChild(profileFile.getBaseName() + ".html"); + + env.getReporter().handle(Event.info("Creating HTML output in " + htmlFile)); + + HtmlCreator.create( + info, + htmlFile, + phaseSummaryStatistics, + phaseStatistics, + opts.htmlDetails, + opts.htmlPixelsPerSecond, + opts.vfsStatsLimit, + opts.chart, + opts.htmlHistograms); + } else { + CriticalPathStatistics critPathStats = new CriticalPathStatistics(info); + new PhaseText( + out, + phaseSummaryStatistics, + phaseStatistics, + Optional.of(critPathStats), + info.getMissingActionsCount(), + opts.vfsStatsLimit) + .print(); + } + } catch (IOException e) { + System.out.println(e); + env + .getReporter() + .handle(Event.error("Failed to analyze profile file(s): " + e.getMessage())); + } } } } -- cgit v1.2.3