Log count and size of output files and top-level files seen this build to the BEP. Augment existing logging for source files to log count in addition to size.
PiperOrigin-RevId: 354612893
diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java b/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java
index 7a5d7e6..de5bf46 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java
@@ -20,6 +20,7 @@
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.FileArtifactValue;
import com.google.devtools.build.lib.actions.MetadataProvider;
+import com.google.devtools.build.lib.skyframe.TreeArtifactValue;
import com.google.devtools.build.lib.vfs.FileStatus;
import java.io.IOException;
import javax.annotation.Nullable;
@@ -60,6 +61,9 @@
*/
ImmutableSet<TreeFileArtifact> getTreeArtifactChildren(SpecialArtifact treeArtifact);
+ /** Retrieves the metadata for this tree artifact. Data should already be available. */
+ TreeArtifactValue getTreeArtifactValue(SpecialArtifact treeArtifact) throws IOException;
+
/**
* Marks an {@link Artifact} as intentionally omitted.
*
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 0802821..9a06765 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
@@ -729,14 +729,16 @@
message BuildMetrics {
message ActionSummary {
- // The total number of actions created and registered during the build.
- // This includes unused actions that were constructed but
- // not executed during this build.
+ // The total number of actions created and registered during the build. This
+ // includes unused actions that were constructed but not executed during
+ // this build. It does not include actions that were created on prior builds
+ // that are still valid, even if those actions had to be re-executed on this
+ // build. For the total number of actions that would be created if this
+ // invocation were "clean", see BuildGraphMetrics below.
int64 actions_created = 1;
- // The total number of actions executed during the build.
- // This includes any remote cache hits, but excludes
- // local action cache hits.
+ // The total number of actions executed during the build. This includes any
+ // remote cache hits, but excludes local action cache hits.
int64 actions_executed = 2;
}
ActionSummary action_summary = 1;
@@ -754,12 +756,14 @@
MemoryMetrics memory_metrics = 2;
message TargetMetrics {
- // Number of targets loaded during this build.
+ // Number of targets loaded during this build. Does not include targets that
+ // were loaded on prior builds on this server and were cached.
int64 targets_loaded = 1;
- // Number of targets configured during this build. This can
- // be greater than targets_loaded if the same target is configured
- // multiple times.
+ // Number of targets configured during this build. This can be greater than
+ // targets_loaded if the same target is configured multiple times. Does not
+ // include targets that were configured on prior builds on this server and
+ // were cached. See BuildGraphMetrics below if you need that.
int64 targets_configured = 2;
}
TargetMetrics target_metrics = 3;
@@ -794,9 +798,29 @@
CumulativeMetrics cumulative_metrics = 6;
message ArtifactMetrics {
- // Total size of all source files newly read this build. Will not include
+ reserved 1;
+
+ message FilesMetric {
+ int64 size_in_bytes = 1;
+ int32 count = 2;
+ }
+
+ // Measures all source files newly read this build. Does not include
// unchanged sources on incremental builds.
- int64 source_artifact_bytes_read = 1;
+ FilesMetric source_artifacts_read = 2;
+ // Measures all output artifacts from executed actions. This includes
+ // actions that were cached locally (via the action cache) or remotely (via
+ // a remote cache or executor), but does *not* include outputs of actions
+ // that were cached internally in Skyframe.
+ FilesMetric output_artifacts_seen = 3;
+ // Measures all output artifacts from actions that were cached locally
+ // via the action cache. These artifacts were already present on disk at the
+ // start of the build. Does not include Skyframe-cached actions' outputs.
+ FilesMetric output_artifacts_from_action_cache = 4;
+ // Measures all artifacts that belong to a top-level output group. Does not
+ // deduplicate, so if there are two top-level targets in this build that
+ // share an artifact, it will be counted twice.
+ FilesMetric top_level_artifacts = 5;
}
ArtifactMetrics artifact_metrics = 7;
@@ -804,13 +828,16 @@
// Information about the size and shape of the build graph. Some fields may
// not be populated if Bazel was able to skip steps due to caching.
message BuildGraphMetrics {
- // How many configured targets/aspects were in this build.
+ // How many configured targets/aspects were in this build, including any
+ // that were analyzed on a prior build and are still valid. May not be
+ // populated if analysis phase was fully cached.
int32 action_lookup_value_count = 1;
- // How many actions belonged to those configured targets/aspects. It may not
- // be necessary to execute all of these actions to build the requested
- // targets.
+ // How many actions belonged to the configured targets/aspects above. It may
+ // not be necessary to execute all of these actions to build the requested
+ // targets. May not be populated if analysis phase was fully cached.
int32 action_count = 2;
- // How many artifacts are outputs of the above actions.
+ // How many artifacts are outputs of the above actions. May not be populated
+ // if analysis phase was fully cached.
int32 output_artifact_count = 3;
// How many Skyframe nodes there are in memory at the end of the build. This
// may underestimate the number of nodes when running with memory-saving
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 5ef677b..11db50d 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
@@ -117,7 +117,11 @@
@SuppressWarnings("unused")
@Subscribe
public void onExecutionComplete(ExecutionFinishedEvent event) {
- artifactMetrics.setSourceArtifactBytesRead(event.sourceArtifactBytesRead());
+ artifactMetrics
+ .setSourceArtifactsRead(event.sourceArtifactsRead())
+ .setOutputArtifactsSeen(event.outputArtifactsSeen())
+ .setOutputArtifactsFromActionCache(event.outputArtifactsFromActionCache())
+ .setTopLevelArtifacts(event.topLevelArtifacts());
}
@SuppressWarnings("unused")
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionInputMapHelper.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionInputMapHelper.java
index 9fd9c34..b367356 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionInputMapHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionInputMapHelper.java
@@ -39,6 +39,28 @@
private ActionInputMapHelper() {}
+ static void addToMap(
+ ActionInputMapSink inputMap,
+ Map<Artifact, ImmutableCollection<Artifact>> expandedArtifacts,
+ Map<SpecialArtifact, ArchivedTreeArtifact> archivedTreeArtifacts,
+ Map<Artifact, ImmutableList<FilesetOutputSymlink>> filesetsInsideRunfiles,
+ Map<Artifact, ImmutableList<FilesetOutputSymlink>> topLevelFilesets,
+ Artifact key,
+ SkyValue value,
+ Environment env)
+ throws InterruptedException {
+ addToMap(
+ inputMap,
+ expandedArtifacts,
+ archivedTreeArtifacts,
+ filesetsInsideRunfiles,
+ topLevelFilesets,
+ key,
+ value,
+ env,
+ MetadataConsumerForMetrics.NO_OP);
+ }
+
/**
* Adds a value obtained by an Artifact skyvalue lookup to the action input map. May do Skyframe
* lookups.
@@ -51,19 +73,23 @@
Map<Artifact, ImmutableList<FilesetOutputSymlink>> topLevelFilesets,
Artifact key,
SkyValue value,
- Environment env)
+ Environment env,
+ MetadataConsumerForMetrics consumer)
throws InterruptedException {
if (value instanceof AggregatingArtifactValue) {
AggregatingArtifactValue aggregatingValue = (AggregatingArtifactValue) value;
for (Pair<Artifact, FileArtifactValue> entry : aggregatingValue.getFileArtifacts()) {
Artifact artifact = entry.first;
- inputMap.put(artifact, entry.second, /*depOwner=*/ key);
+ inputMap.put(artifact, entry.getSecond(), /*depOwner=*/ key);
if (artifact.isFileset()) {
ImmutableList<FilesetOutputSymlink> expandedFileset =
getFilesets(env, (SpecialArtifact) artifact);
if (expandedFileset != null) {
filesetsInsideRunfiles.put(artifact, expandedFileset);
+ consumer.accumulate(expandedFileset);
}
+ } else {
+ consumer.accumulate(entry.getSecond());
}
}
for (Pair<Artifact, TreeArtifactValue> entry : aggregatingValue.getTreeArtifacts()) {
@@ -74,6 +100,7 @@
archivedTreeArtifacts,
inputMap,
/*depOwner=*/ key);
+ consumer.accumulate(entry.getSecond());
}
// We have to cache the "digest" of the aggregating value itself, because the action cache
// checker may want it.
@@ -92,21 +119,32 @@
expandedArtifacts.put(key, expansionBuilder.build());
}
} else if (value instanceof TreeArtifactValue) {
+ TreeArtifactValue treeArtifactValue = (TreeArtifactValue) value;
expandTreeArtifactAndPopulateArtifactData(
key,
- (TreeArtifactValue) value,
+ treeArtifactValue,
expandedArtifacts,
archivedTreeArtifacts,
inputMap,
/*depOwner=*/ key);
+ consumer.accumulate(treeArtifactValue);
} else if (value instanceof ActionExecutionValue) {
- inputMap.put(key, ((ActionExecutionValue) value).getExistingFileArtifactValue(key), key);
+ FileArtifactValue metadata = ((ActionExecutionValue) value).getExistingFileArtifactValue(key);
+ inputMap.put(key, metadata, key);
if (key.isFileset()) {
- topLevelFilesets.put(key, getFilesets(env, (SpecialArtifact) key));
+ ImmutableList<FilesetOutputSymlink> filesets = getFilesets(env, (SpecialArtifact) key);
+ if (filesets != null) {
+ topLevelFilesets.put(key, filesets);
+ consumer.accumulate(filesets);
+ }
+ } else {
+ consumer.accumulate(metadata);
}
} else {
Preconditions.checkArgument(value instanceof FileArtifactValue, "Unexpected value %s", value);
- inputMap.put(key, (FileArtifactValue) value, /*depOwner=*/ key);
+ FileArtifactValue metadata = (FileArtifactValue) value;
+ inputMap.put(key, metadata, /*depOwner=*/ key);
+ consumer.accumulate(metadata);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java
index fbdc927..81bc902 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java
@@ -17,6 +17,7 @@
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
+import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
@@ -303,7 +304,8 @@
store.putArtifactData(artifact, FileArtifactValue.createProxy(digest));
}
- private TreeArtifactValue getTreeArtifactValue(SpecialArtifact artifact) throws IOException {
+ @Override
+ public TreeArtifactValue getTreeArtifactValue(SpecialArtifact artifact) throws IOException {
checkState(artifact.isTreeArtifact(), "%s is not a tree artifact", artifact);
TreeArtifactValue value = store.getTreeArtifactData(artifact);
@@ -470,6 +472,15 @@
return store;
}
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("outputs", outputs)
+ .add("store", store)
+ .add("inputArtifactDataSize", inputArtifactData.size())
+ .toString();
+ }
+
/** Constructs a new {@link FileArtifactValue} by reading from the file system. */
private FileArtifactValue constructFileArtifactValueFromFilesystem(Artifact artifact)
throws IOException {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
index 0f3fb05..09e3bdd 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ArtifactFunction.java
@@ -54,7 +54,6 @@
import java.util.Comparator;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;
import javax.annotation.Nullable;
@@ -66,7 +65,7 @@
*/
class ArtifactFunction implements SkyFunction {
private final Supplier<Boolean> mkdirForTreeArtifacts;
- private final AtomicLong sourceArtifactBytesReadThisBuild;
+ private final MetadataConsumerForMetrics sourceArtifactsSeen;
public static final class MissingFileArtifactValue implements SkyValue {
private final DetailedExitCode detailedExitCode;
@@ -90,9 +89,9 @@
}
public ArtifactFunction(
- Supplier<Boolean> mkdirForTreeArtifacts, AtomicLong sourceArtifactBytesReadThisBuild) {
+ Supplier<Boolean> mkdirForTreeArtifacts, MetadataConsumerForMetrics sourceArtifactsSeen) {
this.mkdirForTreeArtifacts = mkdirForTreeArtifacts;
- this.sourceArtifactBytesReadThisBuild = sourceArtifactBytesReadThisBuild;
+ this.sourceArtifactsSeen = sourceArtifactsSeen;
}
@Override
@@ -273,14 +272,14 @@
}
if (!fileValue.isDirectory() || !TrackSourceDirectoriesFlag.trackSourceDirectories()) {
- if (fileValue.isFile()) {
- sourceArtifactBytesReadThisBuild.addAndGet(fileValue.getSize());
- }
+ FileArtifactValue metadata;
try {
- return FileArtifactValue.createForSourceArtifact(artifact, fileValue);
+ metadata = FileArtifactValue.createForSourceArtifact(artifact, fileValue);
} catch (IOException e) {
return makeIOExceptionSourceInputFileValue(artifact, e);
}
+ sourceArtifactsSeen.accumulate(metadata);
+ return metadata;
}
// For directory artifacts that are not Filesets, we initiate a directory traversal here, and
// compute a hash from the directory structure.
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectCompletor.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectCompletor.java
index e9f3dc2..5420d83 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectCompletor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectCompletor.java
@@ -42,9 +42,14 @@
implements Completor<AspectValue, AspectCompletionValue, AspectCompletionKey, BuildEventId> {
static SkyFunction aspectCompletionFunction(
- PathResolverFactory pathResolverFactory, SkyframeActionExecutor skyframeActionExecutor) {
+ PathResolverFactory pathResolverFactory,
+ SkyframeActionExecutor skyframeActionExecutor,
+ MetadataConsumerForMetrics.FilesMetricConsumer topLevelArtifactsMetric) {
return new CompletionFunction<>(
- pathResolverFactory, new AspectCompletor(), skyframeActionExecutor);
+ pathResolverFactory,
+ new AspectCompletor(),
+ skyframeActionExecutor,
+ topLevelArtifactsMetric);
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
index 9a6ea87..7726e14e 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -157,6 +157,7 @@
":local_repository_lookup_value",
":managed_directories_knowledge",
":map_as_package_roots",
+ ":metadata_consumer_for_metrics",
":output_store",
":package_error_function",
":package_error_message_function",
@@ -417,6 +418,7 @@
deps = [
":action_execution_value",
":aggregating_artifact_value",
+ ":metadata_consumer_for_metrics",
":runfiles_artifact_value",
":tree_artifact_value",
"//src/main/java/com/google/devtools/build/lib/actions",
@@ -779,6 +781,7 @@
":action_template_expansion_value",
":aggregating_artifact_value",
":coverage_report_value",
+ ":metadata_consumer_for_metrics",
":recursive_filesystem_traversal",
":runfiles_artifact_value",
":track_source_directories_flag",
@@ -1361,7 +1364,10 @@
java_library(
name = "execution_finished_event",
srcs = ["ExecutionFinishedEvent.java"],
- deps = ["//third_party:auto_value"],
+ deps = [
+ "//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
+ "//third_party:auto_value",
+ ],
)
java_library(
@@ -1670,6 +1676,19 @@
)
java_library(
+ name = "metadata_consumer_for_metrics",
+ srcs = ["MetadataConsumerForMetrics.java"],
+ deps = [
+ "//src/main/java/com/google/devtools/build/lib/actions:file_metadata",
+ "//src/main/java/com/google/devtools/build/lib/actions:fileset_output_symlink",
+ "//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
+ "//src/main/java/com/google/devtools/build/lib/concurrent",
+ "//src/main/java/com/google/devtools/build/lib/skyframe:tree_artifact_value",
+ "//third_party:guava",
+ ],
+)
+
+java_library(
name = "mutable_supplier",
srcs = ["MutableSupplier.java"],
deps = ["//third_party:guava"],
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
index a2cb5f2..3ae7437 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/CompletionFunction.java
@@ -43,6 +43,7 @@
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.skyframe.ArtifactFunction.MissingFileArtifactValue;
import com.google.devtools.build.lib.skyframe.CompletionFunction.TopLevelActionLookupKey;
+import com.google.devtools.build.lib.skyframe.MetadataConsumerForMetrics.FilesMetricConsumer;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
@@ -156,14 +157,17 @@
private final PathResolverFactory pathResolverFactory;
private final Completor<ValueT, ResultT, KeyT, FailureT> completor;
private final SkyframeActionExecutor skyframeActionExecutor;
+ private final FilesMetricConsumer topLevelArtifactsMetric;
CompletionFunction(
PathResolverFactory pathResolverFactory,
Completor<ValueT, ResultT, KeyT, FailureT> completor,
- SkyframeActionExecutor skyframeActionExecutor) {
+ SkyframeActionExecutor skyframeActionExecutor,
+ FilesMetricConsumer topLevelArtifactsMetric) {
this.pathResolverFactory = pathResolverFactory;
this.completor = completor;
this.skyframeActionExecutor = skyframeActionExecutor;
+ this.topLevelArtifactsMetric = topLevelArtifactsMetric;
}
@SuppressWarnings("unchecked") // Cast to KeyT
@@ -202,6 +206,8 @@
MissingInputFileException missingInputException = null;
NestedSetBuilder<Cause> rootCausesBuilder = NestedSetBuilder.stableOrder();
ImmutableSet.Builder<Artifact> builtArtifactsBuilder = ImmutableSet.builder();
+ // Don't double-count files due to Skyframe restarts.
+ FilesMetricConsumer currentConsumer = new FilesMetricConsumer();
for (Artifact input : allArtifacts) {
try {
SkyValue artifactValue = inputDeps.get(Artifact.key(input)).get();
@@ -225,7 +231,8 @@
topLevelFilesets,
input,
artifactValue,
- env);
+ env,
+ currentConsumer);
}
}
} catch (ActionExecutionException e) {
@@ -312,6 +319,7 @@
return null;
}
env.getListener().post(postable);
+ topLevelArtifactsMetric.mergeIn(currentConsumer);
return completor.getResult();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ExecutionFinishedEvent.java b/src/main/java/com/google/devtools/build/lib/skyframe/ExecutionFinishedEvent.java
index d593911..0c4b56d 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/ExecutionFinishedEvent.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ExecutionFinishedEvent.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.skyframe;
import com.google.auto.value.AutoValue;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.ArtifactMetrics;
import java.time.Duration;
/**
@@ -24,13 +25,17 @@
public abstract class ExecutionFinishedEvent {
// AutoValue Builders require that all fields are populated, so we provide a default.
public static ExecutionFinishedEvent.Builder builderWithDefaults() {
+ ArtifactMetrics.FilesMetric emptyFilesMetric = ArtifactMetrics.FilesMetric.getDefaultInstance();
return builder()
.setOutputDirtyFiles(0)
.setOutputModifiedFilesDuringPreviousBuild(0)
.setSourceDiffCheckingDuration(Duration.ZERO)
.setNumSourceFilesCheckedBecauseOfMissingDiffs(0)
.setOutputTreeDiffCheckingDuration(Duration.ZERO)
- .setSourceArtifactBytesRead(0L);
+ .setSourceArtifactsRead(emptyFilesMetric)
+ .setOutputArtifactsSeen(emptyFilesMetric)
+ .setOutputArtifactsFromActionCache(emptyFilesMetric)
+ .setTopLevelArtifacts(emptyFilesMetric);
}
public abstract int outputDirtyFiles();
@@ -43,7 +48,13 @@
public abstract Duration outputTreeDiffCheckingDuration();
- public abstract long sourceArtifactBytesRead();
+ public abstract ArtifactMetrics.FilesMetric sourceArtifactsRead();
+
+ public abstract ArtifactMetrics.FilesMetric outputArtifactsSeen();
+
+ public abstract ArtifactMetrics.FilesMetric outputArtifactsFromActionCache();
+
+ public abstract ArtifactMetrics.FilesMetric topLevelArtifacts();
static Builder builder() {
return new AutoValue_ExecutionFinishedEvent.Builder();
@@ -63,7 +74,13 @@
abstract Builder setOutputTreeDiffCheckingDuration(Duration outputTreeDiffCheckingDuration);
- abstract Builder setSourceArtifactBytesRead(long sourceArtifactBytesRead);
+ public abstract Builder setSourceArtifactsRead(ArtifactMetrics.FilesMetric value);
+
+ public abstract Builder setOutputArtifactsSeen(ArtifactMetrics.FilesMetric value);
+
+ public abstract Builder setOutputArtifactsFromActionCache(ArtifactMetrics.FilesMetric value);
+
+ public abstract Builder setTopLevelArtifacts(ArtifactMetrics.FilesMetric value);
abstract ExecutionFinishedEvent build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/MetadataConsumerForMetrics.java b/src/main/java/com/google/devtools/build/lib/skyframe/MetadataConsumerForMetrics.java
new file mode 100644
index 0000000..9a679f0
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/MetadataConsumerForMetrics.java
@@ -0,0 +1,97 @@
+// Copyright 2021 The Bazel Authors. All rights reserved.
+//
+// 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 com.google.devtools.build.lib.skyframe;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.actions.FileArtifactValue;
+import com.google.devtools.build.lib.actions.FileStateType;
+import com.google.devtools.build.lib.actions.FilesetOutputSymlink;
+import com.google.devtools.build.lib.buildeventstream.BuildEventStreamProtos.BuildMetrics.ArtifactMetrics;
+import com.google.devtools.build.lib.concurrent.ThreadSafety;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/** Sink for file-related metadata to be used for metrics gathering. */
+@ThreadSafety.ThreadSafe
+public interface MetadataConsumerForMetrics {
+ MetadataConsumerForMetrics NO_OP =
+ new MetadataConsumerForMetrics() {
+ @Override
+ public void accumulate(FileArtifactValue metadata) {}
+
+ @Override
+ public void accumulate(TreeArtifactValue treeArtifactValue) {}
+
+ @Override
+ public void accumulate(ImmutableList<FilesetOutputSymlink> filesetOutputSymlinks) {}
+ };
+
+ void accumulate(FileArtifactValue metadata);
+
+ void accumulate(TreeArtifactValue treeArtifactValue);
+
+ void accumulate(ImmutableList<FilesetOutputSymlink> filesetOutputSymlinks);
+
+ /** Accumulates file metadata for later export to a {@link ArtifactMetrics.FilesMetric} object. */
+ class FilesMetricConsumer implements MetadataConsumerForMetrics {
+ private final AtomicLong size = new AtomicLong();
+ private final AtomicInteger count = new AtomicInteger();
+
+ @Override
+ public void accumulate(FileArtifactValue metadata) {
+ // Exclude directories (might throw in future) and symlinks (duplicate data). In practice,
+ // most symlinks' metadata is that of their target, so they still get duplicated.
+ if (metadata.getType() == FileStateType.REGULAR_FILE) {
+ size.addAndGet(metadata.getSize());
+ count.incrementAndGet();
+ }
+ }
+
+ @Override
+ public void accumulate(TreeArtifactValue treeArtifactValue) {
+ long totalChildBytes = treeArtifactValue.getTotalChildBytes();
+ size.addAndGet(totalChildBytes);
+ if (totalChildBytes > 0) {
+ // Skip omitted/missing tree artifacts: they will throw here.
+ count.addAndGet(treeArtifactValue.getChildren().size());
+ }
+ }
+
+ @Override
+ public void accumulate(ImmutableList<FilesetOutputSymlink> filesetOutputSymlinks) {
+ // This is a bit of a fudge: we include the symlinks as a count, but don't count their
+ // targets' sizes, because (a) plumbing the data is hard, (b) it would double-count symlinks
+ // to output files, and (c) it's not even uniquely generated content for input files.
+ count.addAndGet(filesetOutputSymlinks.size());
+ }
+
+ @ThreadSafety.ThreadSafe
+ public void mergeIn(FilesMetricConsumer otherConsumer) {
+ this.size.addAndGet(otherConsumer.size.get());
+ this.count.addAndGet(otherConsumer.count.get());
+ }
+
+ ArtifactMetrics.FilesMetric toFilesMetricAndReset() {
+ return ArtifactMetrics.FilesMetric.newBuilder()
+ .setSizeInBytes(size.getAndSet(0L))
+ .setCount(count.getAndSet(0))
+ .build();
+ }
+
+ void reset() {
+ size.set(0L);
+ count.set(0);
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/OutputStore.java b/src/main/java/com/google/devtools/build/lib/skyframe/OutputStore.java
index 9e7588e..79b3e05 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/OutputStore.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/OutputStore.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
@@ -91,4 +92,12 @@
artifactData.remove(artifact);
}
}
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("artifactData", artifactData)
+ .add("treeArtifactData", treeArtifactData)
+ .toString();
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java
index 4bf6271..252a624 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java
@@ -74,6 +74,7 @@
import com.google.devtools.build.lib.actions.cache.MetadataHandler;
import com.google.devtools.build.lib.actions.cache.MetadataInjector;
import com.google.devtools.build.lib.analysis.config.CoreOptions;
+import com.google.devtools.build.lib.bugreport.BugReport;
import com.google.devtools.build.lib.buildtool.BuildRequestOptions;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -154,6 +155,8 @@
};
private final ActionKeyContext actionKeyContext;
+ private final MetadataConsumerForMetrics outputArtifactsSeen;
+ private final MetadataConsumerForMetrics outputArtifactsFromActionCache;
private Reporter reporter;
private Map<String, String> clientEnv = ImmutableMap.of();
private Executor executorEngine;
@@ -226,9 +229,13 @@
SkyframeActionExecutor(
ActionKeyContext actionKeyContext,
+ MetadataConsumerForMetrics outputArtifactsSeen,
+ MetadataConsumerForMetrics outputArtifactsFromActionCache,
AtomicReference<ActionExecutionStatusReporter> statusReporterRef,
Supplier<ImmutableList<Root>> sourceRootSupplier) {
this.actionKeyContext = actionKeyContext;
+ this.outputArtifactsSeen = outputArtifactsSeen;
+ this.outputArtifactsFromActionCache = outputArtifactsFromActionCache;
this.statusReporterRef = statusReporterRef;
this.sourceRootSupplier = sourceRootSupplier;
}
@@ -643,7 +650,12 @@
}
// We still need to check the outputs so that output file data is available to the value.
- checkOutputs(action, metadataHandler);
+ // Filesets cannot be cached in the action cache, so it is fine to pass null here.
+ checkOutputs(
+ action,
+ metadataHandler,
+ /*filesetOutputSymlinksForMetrics=*/ null,
+ /*isActionCacheHitForMetrics=*/ true);
if (!eventPosted) {
eventHandler.post(new CachedActionEvent(action, actionStartTime));
}
@@ -1110,7 +1122,11 @@
Preconditions.checkState(action.inputsDiscovered(),
"Action %s successfully executed, but inputs still not known", action);
- if (!checkOutputs(action, metadataHandler)) {
+ if (!checkOutputs(
+ action,
+ metadataHandler,
+ actionExecutionContext.getOutputSymlinks(),
+ /*isActionCacheHitForMetrics=*/ false)) {
throw toActionExecutionException(
"not all outputs were created or valid",
null,
@@ -1546,7 +1562,11 @@
*
* @return false if some outputs are missing, true - otherwise.
*/
- private boolean checkOutputs(Action action, MetadataHandler metadataHandler) {
+ private boolean checkOutputs(
+ Action action,
+ MetadataHandler metadataHandler,
+ @Nullable ImmutableList<FilesetOutputSymlink> filesetOutputSymlinksForMetrics,
+ boolean isActionCacheHitForMetrics) {
boolean success = true;
for (Artifact output : action.getOutputs()) {
// getMetadata has the side effect of adding the artifact to the cache if it's not there
@@ -1554,7 +1574,15 @@
// call it if we know the artifact is not omitted.
if (!metadataHandler.artifactOmitted(output)) {
try {
- metadataHandler.getMetadata(output);
+ FileArtifactValue metadata = metadataHandler.getMetadata(output);
+
+ addOutputToMetrics(
+ output,
+ metadata,
+ metadataHandler,
+ filesetOutputSymlinksForMetrics,
+ isActionCacheHitForMetrics,
+ action);
} catch (IOException e) {
success = false;
if (output.isTreeArtifact()) {
@@ -1569,6 +1597,48 @@
return success;
}
+ private void addOutputToMetrics(
+ Artifact output,
+ FileArtifactValue metadata,
+ MetadataHandler metadataHandler,
+ @Nullable ImmutableList<FilesetOutputSymlink> filesetOutputSymlinks,
+ boolean isActionCacheHit,
+ Action actionForDebugging)
+ throws IOException {
+ if (metadata == null) {
+ BugReport.sendBugReport(
+ new IllegalStateException(
+ String.format(
+ "Metadata for %s not present in %s (for %s)",
+ output, metadataHandler, actionForDebugging)));
+ return;
+ }
+ if (output.isFileset() && filesetOutputSymlinks != null) {
+ outputArtifactsSeen.accumulate(filesetOutputSymlinks);
+ } else if (!output.isTreeArtifact()) {
+ outputArtifactsSeen.accumulate(metadata);
+ if (isActionCacheHit) {
+ outputArtifactsFromActionCache.accumulate(metadata);
+ }
+ } else {
+ TreeArtifactValue treeArtifactValue;
+ try {
+ treeArtifactValue = metadataHandler.getTreeArtifactValue((SpecialArtifact) output);
+ } catch (IOException e) {
+ BugReport.sendBugReport(
+ new IllegalStateException(
+ String.format(
+ "Unexpected IO exception after metadata %s was retrieved for %s (action %s)",
+ metadata, output, actionForDebugging)));
+ throw e;
+ }
+ outputArtifactsSeen.accumulate(treeArtifactValue);
+ if (isActionCacheHit) {
+ outputArtifactsFromActionCache.accumulate(treeArtifactValue);
+ }
+ }
+ }
+
/**
* Convenience function for creating an ActionExecutionException reporting that the action failed
* due to the exception cause, if there is an additional explanatory message that clarifies the
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 3d12bc4..dc36577 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -152,6 +152,7 @@
import com.google.devtools.build.lib.skyframe.DirtinessCheckerUtils.FileDirtinessChecker;
import com.google.devtools.build.lib.skyframe.ExternalFilesHelper.ExternalFileAction;
import com.google.devtools.build.lib.skyframe.FileFunction.NonexistentFileReceiver;
+import com.google.devtools.build.lib.skyframe.MetadataConsumerForMetrics.FilesMetricConsumer;
import com.google.devtools.build.lib.skyframe.PackageFunction.ActionOnIOExceptionReadingBuildFile;
import com.google.devtools.build.lib.skyframe.PackageFunction.IncrementalityIntent;
import com.google.devtools.build.lib.skyframe.PackageFunction.LoadedPackageCacheEntry;
@@ -217,7 +218,6 @@
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -251,10 +251,14 @@
protected final ExternalFilesHelper externalFilesHelper;
private final GraphInconsistencyReceiver graphInconsistencyReceiver;
/**
- * Tracks the accumulated size of source artifacts read this build. Does not include cached
- * artifacts, so is not useful on incremental builds.
+ * Measures source artifacts read this build. Does not include cached artifacts, so is less useful
+ * on incremental builds.
*/
- private final AtomicLong sourceArtifactBytesReadThisBuild = new AtomicLong();
+ private final FilesMetricConsumer sourceArtifactsSeen = new FilesMetricConsumer();
+
+ private final FilesMetricConsumer outputArtifactsSeen = new FilesMetricConsumer();
+ private final FilesMetricConsumer outputArtifactsFromActionCache = new FilesMetricConsumer();
+ private final FilesMetricConsumer topLevelArtifactsMetric = new FilesMetricConsumer();
@Nullable protected OutputService outputService;
@@ -441,7 +445,12 @@
this.ruleClassProvider = (ConfiguredRuleClassProvider) pkgFactory.getRuleClassProvider();
this.defaultBuildOptions = defaultBuildOptions;
this.skyframeActionExecutor =
- new SkyframeActionExecutor(actionKeyContext, statusReporterRef, this::getPathEntries);
+ new SkyframeActionExecutor(
+ actionKeyContext,
+ outputArtifactsSeen,
+ outputArtifactsFromActionCache,
+ statusReporterRef,
+ this::getPathEntries);
this.artifactFactory =
new ArtifactFactory(
/* execRootParent= */ directories.getExecRootBase(),
@@ -586,16 +595,18 @@
map.put(SkyFunctions.EXTERNAL_PACKAGE, new ExternalPackageFunction(externalPackageHelper));
map.put(
SkyFunctions.TARGET_COMPLETION,
- TargetCompletor.targetCompletionFunction(pathResolverFactory, skyframeActionExecutor));
+ TargetCompletor.targetCompletionFunction(
+ pathResolverFactory, skyframeActionExecutor, topLevelArtifactsMetric));
map.put(
SkyFunctions.ASPECT_COMPLETION,
- AspectCompletor.aspectCompletionFunction(pathResolverFactory, skyframeActionExecutor));
+ AspectCompletor.aspectCompletionFunction(
+ pathResolverFactory, skyframeActionExecutor, topLevelArtifactsMetric));
map.put(SkyFunctions.TEST_COMPLETION, new TestCompletionFunction());
map.put(
Artifact.ARTIFACT,
new ArtifactFunction(
() -> !skyframeActionExecutor.actionFileSystemType().inMemoryFileSystem(),
- sourceArtifactBytesReadThisBuild));
+ sourceArtifactsSeen));
map.put(
SkyFunctions.BUILD_INFO_COLLECTION,
new BuildInfoCollectionFunction(actionKeyContext, artifactFactory));
@@ -2705,7 +2716,10 @@
incrementalBuildMonitor = new SkyframeIncrementalBuildMonitor();
invalidateTransientErrors();
- sourceArtifactBytesReadThisBuild.set(0L);
+ sourceArtifactsSeen.reset();
+ outputArtifactsSeen.reset();
+ outputArtifactsFromActionCache.reset();
+ topLevelArtifactsMetric.reset();
}
private void getActionEnvFromOptions(CoreOptions opt) {
@@ -3028,7 +3042,10 @@
public final ExecutionFinishedEvent createExecutionFinishedEvent() {
return createExecutionFinishedEventInternal()
- .setSourceArtifactBytesRead(sourceArtifactBytesReadThisBuild.getAndSet(0L))
+ .setSourceArtifactsRead(sourceArtifactsSeen.toFilesMetricAndReset())
+ .setOutputArtifactsSeen(outputArtifactsSeen.toFilesMetricAndReset())
+ .setOutputArtifactsFromActionCache(outputArtifactsFromActionCache.toFilesMetricAndReset())
+ .setTopLevelArtifacts(topLevelArtifactsMetric.toFilesMetricAndReset())
.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TargetCompletor.java b/src/main/java/com/google/devtools/build/lib/skyframe/TargetCompletor.java
index 378d34b..3e5143e 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TargetCompletor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TargetCompletor.java
@@ -42,9 +42,14 @@
TargetCompletionKey,
ConfiguredTargetAndData> {
static SkyFunction targetCompletionFunction(
- PathResolverFactory pathResolverFactory, SkyframeActionExecutor skyframeActionExecutor) {
+ PathResolverFactory pathResolverFactory,
+ SkyframeActionExecutor skyframeActionExecutor,
+ MetadataConsumerForMetrics.FilesMetricConsumer topLevelArtifactsMetric) {
return new CompletionFunction<>(
- pathResolverFactory, new TargetCompletor(), skyframeActionExecutor);
+ pathResolverFactory,
+ new TargetCompletor(),
+ skyframeActionExecutor,
+ topLevelArtifactsMetric);
}
@Override
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java
index e02e068..777643e 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/TreeArtifactValue.java
@@ -28,6 +28,7 @@
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
import com.google.devtools.build.lib.actions.FileArtifactValue;
+import com.google.devtools.build.lib.actions.FileStateType;
import com.google.devtools.build.lib.actions.HasDigest;
import com.google.devtools.build.lib.actions.cache.MetadataDigestUtils;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
@@ -150,11 +151,13 @@
new TreeArtifactValue(
MetadataDigestUtils.fromMetadata(ImmutableMap.of()),
ImmutableSortedMap.of(),
+ 0L,
/*archivedRepresentation=*/ null,
/*entirelyRemote=*/ false);
private final byte[] digest;
private final ImmutableSortedMap<TreeFileArtifact, FileArtifactValue> childData;
+ private final long totalChildSize;
/**
* Optional archived representation of the entire tree artifact which can be sent instead of all
@@ -167,10 +170,12 @@
private TreeArtifactValue(
byte[] digest,
ImmutableSortedMap<TreeFileArtifact, FileArtifactValue> childData,
+ long totalChildSize,
@Nullable ArchivedRepresentation archivedRepresentation,
boolean entirelyRemote) {
this.digest = digest;
this.childData = childData;
+ this.totalChildSize = totalChildSize;
this.archivedRepresentation = archivedRepresentation;
this.entirelyRemote = entirelyRemote;
}
@@ -194,6 +199,10 @@
return childData.keySet();
}
+ public long getTotalChildBytes() {
+ return totalChildSize;
+ }
+
/** Return archived representation of the tree artifact (if present). */
Optional<ArchivedRepresentation> getArchivedRepresentation() {
return Optional.ofNullable(archivedRepresentation);
@@ -264,6 +273,7 @@
return new TreeArtifactValue(
null,
ImmutableSortedMap.of(),
+ 0L,
/*archivedRepresentation=*/ null,
/*entirelyRemote=*/ false) {
@Override
@@ -475,13 +485,19 @@
boolean entirelyRemote =
archivedRepresentation == null || archivedRepresentation.archivedFileValue().isRemote();
+ long totalChildSize = 0;
for (Map.Entry<TreeFileArtifact, FileArtifactValue> childData : finalChildData.entrySet()) {
// Digest will be deterministic because children are sorted.
fingerprint.addPath(childData.getKey().getParentRelativePath());
- childData.getValue().addTo(fingerprint);
+ FileArtifactValue metadata = childData.getValue();
+ metadata.addTo(fingerprint);
// Tolerate a mix of local and remote children (b/152496153#comment80).
- entirelyRemote &= childData.getValue().isRemote();
+ entirelyRemote &= metadata.isRemote();
+
+ if (metadata.getType() == FileStateType.REGULAR_FILE) {
+ totalChildSize += metadata.getSize();
+ }
}
if (archivedRepresentation != null) {
@@ -489,7 +505,11 @@
}
return new TreeArtifactValue(
- fingerprint.digestAndReset(), finalChildData, archivedRepresentation, entirelyRemote);
+ fingerprint.digestAndReset(),
+ finalChildData,
+ totalChildSize,
+ archivedRepresentation,
+ entirelyRemote);
}
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
index a6d72be..c25ed89 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
@@ -966,6 +966,11 @@
}
@Override
+ public TreeArtifactValue getTreeArtifactValue(SpecialArtifact treeArtifact) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public FileArtifactValue constructMetadataForDigest(
Artifact output, FileStatus statNoFollow, byte[] digest) {
throw new UnsupportedOperationException();
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTestCase.java b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTestCase.java
index e533f72..c3c157a 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTestCase.java
@@ -52,7 +52,6 @@
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.UUID;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Before;
@@ -107,7 +106,9 @@
new AtomicReference<>(UnixGlob.DEFAULT_SYSCALLS),
externalFilesHelper))
.put(FileValue.FILE, new FileFunction(pkgLocator))
- .put(Artifact.ARTIFACT, new ArtifactFunction(() -> true, new AtomicLong()))
+ .put(
+ Artifact.ARTIFACT,
+ new ArtifactFunction(() -> true, MetadataConsumerForMetrics.NO_OP))
.put(SkyFunctions.ACTION_EXECUTION, new SimpleActionExecutionFunction())
.put(
SkyFunctions.PACKAGE,
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD
index 091758a..6b2a59e 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -40,6 +40,7 @@
"//src/main/java/com/google/devtools/build/lib/packages",
"//src/main/java/com/google/devtools/build/lib/rules/platform",
"//src/main/java/com/google/devtools/build/lib/skyframe:configured_target_key",
+ "//src/main/java/com/google/devtools/build/lib/skyframe:metadata_consumer_for_metrics",
"//src/main/java/com/google/devtools/build/lib/skyframe:package_value",
"//src/main/java/com/google/devtools/build/lib/skyframe:sky_functions",
"//src/main/java/com/google/devtools/build/lib/skyframe:skyframe_cluster",
@@ -202,6 +203,7 @@
"//src/main/java/com/google/devtools/build/lib/skyframe:glob_value",
"//src/main/java/com/google/devtools/build/lib/skyframe:local_repository_lookup_value",
"//src/main/java/com/google/devtools/build/lib/skyframe:managed_directories_knowledge",
+ "//src/main/java/com/google/devtools/build/lib/skyframe:metadata_consumer_for_metrics",
"//src/main/java/com/google/devtools/build/lib/skyframe:output_store",
"//src/main/java/com/google/devtools/build/lib/skyframe:package_error_message_value",
"//src/main/java/com/google/devtools/build/lib/skyframe:package_lookup_function",
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java
index d23b8b3..54edfbf 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TimestampBuilderTestCase.java
@@ -127,7 +127,6 @@
import java.util.Map;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
import org.junit.Before;
@@ -241,6 +240,8 @@
final SkyframeActionExecutor skyframeActionExecutor =
new SkyframeActionExecutor(
actionKeyContext,
+ MetadataConsumerForMetrics.NO_OP,
+ MetadataConsumerForMetrics.NO_OP,
new AtomicReference<>(statusReporter),
/*sourceRootSupplier=*/ () -> ImmutableList.of());
@@ -262,7 +263,9 @@
new AtomicReference<>(UnixGlob.DEFAULT_SYSCALLS),
externalFilesHelper))
.put(FileValue.FILE, new FileFunction(pkgLocator))
- .put(Artifact.ARTIFACT, new ArtifactFunction(() -> true, new AtomicLong()))
+ .put(
+ Artifact.ARTIFACT,
+ new ArtifactFunction(() -> true, MetadataConsumerForMetrics.NO_OP))
.put(
SkyFunctions.ACTION_EXECUTION,
new ActionExecutionFunction(skyframeActionExecutor, directories, tsgmRef))