Post the build tool logs event from the BuildTool Collect the relevant data in the BuildResult and post the build tool logs event from a central location rather than a module. Maybe not the ideal location, but we have multiple modules that need to contribute to build tool logs, so it must be posted from a common location. It could be in a module, except that would require modules depending on / extending other modules, which we don't support right now. Note that this change includes a fix to LastBuildEvent, without which this wouldn't work since this change is changing the order of the last two events posted. PiperOrigin-RevId: 222061608
diff --git a/src/main/java/com/google/devtools/build/lib/buildeventstream/LastBuildEvent.java b/src/main/java/com/google/devtools/build/lib/buildeventstream/LastBuildEvent.java index 59724a0..1105be6 100644 --- a/src/main/java/com/google/devtools/build/lib/buildeventstream/LastBuildEvent.java +++ b/src/main/java/com/google/devtools/build/lib/buildeventstream/LastBuildEvent.java
@@ -35,6 +35,11 @@ } @Override + public Collection<LocalFile> referencedLocalFiles() { + return event.referencedLocalFiles(); + } + + @Override public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventContext converters) { return BuildEventStreamProtos.BuildEvent.newBuilder(event.asStreamProto(converters)) .setLastMessage(true)
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildResult.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildResult.java index 5ca0204..20cf11f 100644 --- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildResult.java +++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildResult.java
@@ -19,10 +19,16 @@ import com.google.common.base.Preconditions; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection; +import com.google.devtools.build.lib.buildeventstream.BuildToolLogs; import com.google.devtools.build.lib.skyframe.AspectValue; import com.google.devtools.build.lib.util.ExitCode; +import com.google.devtools.build.lib.util.Pair; +import com.google.devtools.build.lib.vfs.Path; +import com.google.protobuf.ByteString; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.List; import javax.annotation.Nullable; /** @@ -45,6 +51,8 @@ private Collection<ConfiguredTarget> skippedTargets; private Collection<AspectValue> successfulAspects; + private final BuildToolLogCollection buildToolLogCollection = new BuildToolLogCollection(); + public BuildResult(long startTimeMillis) { this.startTimeMillis = startTimeMillis; } @@ -241,6 +249,15 @@ return skippedTargets; } + /** + * Collection of data for the build tool logs event. This may only be modified until the + * BuildCompleteEvent is posted; any changes after that event is handled will not be included in + * the build tool logs event. + */ + public BuildToolLogCollection getBuildToolLogCollection() { + return buildToolLogCollection; + } + /** For debugging. */ @Override public String toString() { @@ -253,6 +270,53 @@ .add("actualTargets", actualTargets) .add("testTargets", testTargets) .add("successfulTargets", successfulTargets) + .add("buildToolLogCollection", buildToolLogCollection) .toString(); } + + /** Collection of data for the build tool logs event. */ + public static final class BuildToolLogCollection { + private final List<Pair<String, ByteString>> directValues = new ArrayList<>(); + private final List<Pair<String, String>> directUris = new ArrayList<>(); + private final List<Pair<String, Path>> logFiles = new ArrayList<>(); + private boolean frozen; + + public BuildToolLogCollection freeze() { + frozen = true; + return this; + } + + public BuildToolLogCollection addDirectValue(String name, byte[] data) { + Preconditions.checkState(!frozen); + this.directValues.add(Pair.of(name, ByteString.copyFrom(data))); + return this; + } + + public BuildToolLogCollection addUri(String name, String uri) { + Preconditions.checkState(!frozen); + this.directUris.add(Pair.of(name, uri)); + return this; + } + + public BuildToolLogCollection addLocalFile(String name, Path path) { + Preconditions.checkState(!frozen); + this.logFiles.add(Pair.of(name, path)); + return this; + } + + public BuildToolLogs toEvent() { + Preconditions.checkState(frozen); + return new BuildToolLogs(directValues, directUris, logFiles); + } + + /** For debugging. */ + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("directValues", directValues) + .add("directUris", directUris) + .add("logFiles", logFiles) + .toString(); + } + } }
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java index dd37a7f..844cbca 100644 --- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java +++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
@@ -360,6 +360,7 @@ new BuildCompleteEvent( result, ImmutableList.of(BuildEventId.buildToolLogs(), BuildEventId.buildMetrics()))); + env.getEventBus().post(result.getBuildToolLogCollection().freeze().toEvent()); if (ie != null) { if (exitCondition.equals(ExitCode.SUCCESS)) { result.setExitCondition(ExitCode.INTERRUPTED);
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java index 9f237d4..5b10cf0 100644 --- a/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java +++ b/src/main/java/com/google/devtools/build/lib/runtime/BuildSummaryStatsModule.java
@@ -14,13 +14,11 @@ package com.google.devtools.build.lib.runtime; import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; import com.google.common.eventbus.AllowConcurrentEvents; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import com.google.devtools.build.lib.actions.ActionKeyContext; import com.google.devtools.build.lib.actions.ActionResultReceivedEvent; -import com.google.devtools.build.lib.buildeventstream.BuildToolLogs; import com.google.devtools.build.lib.buildtool.BuildRequest; import com.google.devtools.build.lib.buildtool.buildevent.BuildCompleteEvent; import com.google.devtools.build.lib.buildtool.buildevent.ExecutionStartingEvent; @@ -32,8 +30,7 @@ import com.google.devtools.build.lib.profiler.Profiler; import com.google.devtools.build.lib.profiler.ProfilerTask; import com.google.devtools.build.lib.profiler.SilentCloseable; -import com.google.devtools.build.lib.util.Pair; -import com.google.protobuf.ByteString; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; @@ -93,11 +90,13 @@ public void buildComplete(BuildCompleteEvent event) { try { // We might want to make this conditional on a flag; it can sometimes be a bit of a nuisance. - List<Pair<String, ByteString>> statistics = new ArrayList<>(); List<String> items = new ArrayList<>(); items.add(String.format("Elapsed time: %.3fs", event.getResult().getElapsedSeconds())); - statistics.add(Pair.of("elapsed time", ByteString.copyFromUtf8( - String.format("%f", event.getResult().getElapsedSeconds())))); + event.getResult().getBuildToolLogCollection() + .addDirectValue( + "elapsed time", + String.format( + "%f", event.getResult().getElapsedSeconds()).getBytes(StandardCharsets.UTF_8)); if (criticalPathComputer != null) { try (SilentCloseable c = @@ -105,8 +104,9 @@ AggregatedCriticalPath criticalPath = criticalPathComputer.aggregate(); items.add(criticalPath.toStringSummaryNoRemote()); - statistics.add( - Pair.of("critical path", ByteString.copyFromUtf8(criticalPath.toString()))); + event.getResult().getBuildToolLogCollection() + .addDirectValue( + "critical path", criticalPath.toString().getBytes(StandardCharsets.UTF_8)); logger.info(criticalPath.toString()); logger.info( "Slowest actions:\n " @@ -129,9 +129,9 @@ String spawnSummary = spawnStats.getSummary(); reporter.handle(Event.info(spawnSummary)); - statistics.add(Pair.of("process stats", ByteString.copyFromUtf8(spawnSummary))); - reporter.post(new BuildToolLogs(statistics, ImmutableList.of(), ImmutableList.of())); + event.getResult().getBuildToolLogCollection() + .addDirectValue("process stats", spawnSummary.getBytes(StandardCharsets.UTF_8)); } finally { criticalPathComputer = null; }