From a49c0ff07ed22eed3e18c6ab8544e3fc30647515 Mon Sep 17 00:00:00 2001 From: tomlu Date: Fri, 6 Jul 2018 10:08:34 -0700 Subject: Publish used_heap_size_post_build metric to BEP. This metric measures the used heap size at the end of the build, after a GC. Because this is expensive it is only collected if a flag is passed. RELNOTES: PiperOrigin-RevId: 203492365 --- .../proto/build_event_stream.proto | 8 ++++++ .../com/google/devtools/build/lib/metrics/BUILD | 1 + .../build/lib/metrics/MetricsCollector.java | 29 +++++++++++++++++++--- .../devtools/build/lib/metrics/MetricsModule.java | 24 ++++++++++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib') diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto index 74bdd0be26..7462b115a8 100644 --- a/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/proto/build_event_stream.proto @@ -625,6 +625,14 @@ message BuildMetrics { int64 actions_created = 1; } ActionSummary action_summary = 1; + + message MemoryMetrics { + // Size of the JVM heap post build in bytes. This is only collected if + // --bep_publish_used_heap_size_post_build is set, + // since it forces a full GC. + int64 used_heap_size_post_build = 1; + } + MemoryMetrics memory_metrics = 2; } // Event providing additional statistics/logs after completion of the build. diff --git a/src/main/java/com/google/devtools/build/lib/metrics/BUILD b/src/main/java/com/google/devtools/build/lib/metrics/BUILD index 3bc0665041..67ebbae4bf 100644 --- a/src/main/java/com/google/devtools/build/lib/metrics/BUILD +++ b/src/main/java/com/google/devtools/build/lib/metrics/BUILD @@ -15,6 +15,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib:runtime", "//src/main/java/com/google/devtools/build/lib/buildeventstream", "//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto", + "//src/main/java/com/google/devtools/common/options", "//third_party:guava", ], ) diff --git a/src/main/java/com/google/devtools/build/lib/metrics/MetricsCollector.java b/src/main/java/com/google/devtools/build/lib/metrics/MetricsCollector.java index a273a8beb4..180064c111 100644 --- a/src/main/java/com/google/devtools/build/lib/metrics/MetricsCollector.java +++ b/src/main/java/com/google/devtools/build/lib/metrics/MetricsCollector.java @@ -17,16 +17,24 @@ import com.google.common.eventbus.Subscribe; import com.google.devtools.build.lib.analysis.AnalysisPhaseCompleteEvent; import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics; import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.ActionSummary; +import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.MemoryMetrics; import com.google.devtools.build.lib.buildtool.buildevent.BuildCompleteEvent; +import com.google.devtools.build.lib.metrics.MetricsModule.Options; import com.google.devtools.build.lib.runtime.CommandEnvironment; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryMXBean; class MetricsCollector { private final CommandEnvironment env; + private final boolean bepPublishUsedHeapSizePostBuild; + private int actionsConstructed; MetricsCollector(CommandEnvironment env) { this.env = env; + this.bepPublishUsedHeapSizePostBuild = + env.getOptions().getOptions(Options.class).bepPublishUsedHeapSizePostBuild; env.getEventBus().register(this); } @@ -45,8 +53,23 @@ class MetricsCollector { } private BuildMetrics createBuildMetrics() { - return BuildMetrics.newBuilder() - .setActionSummary(ActionSummary.newBuilder().setActionsCreated(actionsConstructed).build()) - .build(); + BuildMetrics.Builder metrics = BuildMetrics.newBuilder(); + metrics.setActionSummary(createActionSummary()); + metrics.setMemoryMetrics(createMemoryMetrics()); + return metrics.build(); + } + + private ActionSummary createActionSummary() { + return ActionSummary.newBuilder().setActionsCreated(actionsConstructed).build(); + } + + private MemoryMetrics createMemoryMetrics() { + MemoryMetrics.Builder memoryMetrics = MemoryMetrics.newBuilder(); + if (bepPublishUsedHeapSizePostBuild) { + System.gc(); + MemoryMXBean memBean = ManagementFactory.getMemoryMXBean(); + memoryMetrics.setUsedHeapSizePostBuild(memBean.getHeapMemoryUsage().getUsed()); + } + return memoryMetrics.build(); } } diff --git a/src/main/java/com/google/devtools/build/lib/metrics/MetricsModule.java b/src/main/java/com/google/devtools/build/lib/metrics/MetricsModule.java index 0c8c32f5b2..ae4e86edf9 100644 --- a/src/main/java/com/google/devtools/build/lib/metrics/MetricsModule.java +++ b/src/main/java/com/google/devtools/build/lib/metrics/MetricsModule.java @@ -13,8 +13,14 @@ // limitations under the License. package com.google.devtools.build.lib.metrics; +import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.runtime.BlazeModule; +import com.google.devtools.build.lib.runtime.Command; import com.google.devtools.build.lib.runtime.CommandEnvironment; +import com.google.devtools.common.options.Option; +import com.google.devtools.common.options.OptionDocumentationCategory; +import com.google.devtools.common.options.OptionEffectTag; +import com.google.devtools.common.options.OptionsBase; /** * A blaze module that installs metrics instrumentations and issues a {@link BuildMetricsEvent} at @@ -22,6 +28,24 @@ import com.google.devtools.build.lib.runtime.CommandEnvironment; */ public class MetricsModule extends BlazeModule { + /** Metrics options. */ + public static final class Options extends OptionsBase { + @Option( + name = "bep_publish_used_heap_size_post_build", + defaultValue = "false", + documentationCategory = OptionDocumentationCategory.LOGGING, + effectTags = {OptionEffectTag.UNKNOWN}, + help = + "When set we collect and publish used_heap_size_post_build " + + "from build_event_stream.proto. This forces a full GC and is off by default.") + public boolean bepPublishUsedHeapSizePostBuild; + } + + @Override + public Iterable> getCommandOptions(Command command) { + return ImmutableList.of(Options.class); + } + @Override public void beforeCommand(CommandEnvironment env) { MetricsCollector.installInEnv(env); -- cgit v1.2.3