Print the path of too-large stdout/stderr and the flag to increase the limit.
PiperOrigin-RevId: 332503242
diff --git a/src/main/java/com/google/devtools/build/lib/events/BUILD b/src/main/java/com/google/devtools/build/lib/events/BUILD
index aad49b2..cfb4d2d 100644
--- a/src/main/java/com/google/devtools/build/lib/events/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/events/BUILD
@@ -14,6 +14,7 @@
deps = [
"//src/main/java/com/google/devtools/build/lib/util/io",
"//src/main/java/com/google/devtools/build/lib/util/io:out-err",
+ "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
"//src/main/java/net/starlark/java/eval",
"//src/main/java/net/starlark/java/syntax",
"//third_party:guava",
diff --git a/src/main/java/com/google/devtools/build/lib/events/Event.java b/src/main/java/com/google/devtools/build/lib/events/Event.java
index f699405..a7f4f94 100644
--- a/src/main/java/com/google/devtools/build/lib/events/Event.java
+++ b/src/main/java/com/google/devtools/build/lib/events/Event.java
@@ -20,6 +20,7 @@
import com.google.common.collect.ImmutableClassToInstanceMap;
import com.google.devtools.build.lib.util.io.FileOutErr;
+import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
@@ -190,6 +191,16 @@
return getProperty(FileOutErr.class) != null;
}
+ /**
+ * Gets the path to the stdout associated with this event (which the caller must not access), or
+ * null if there is no such path.
+ */
+ @Nullable
+ public PathFragment getStdOutPathFragment() {
+ FileOutErr outErr = getProperty(FileOutErr.class);
+ return outErr == null ? null : outErr.getOutputPathFragment();
+ }
+
/** Gets the size of the stdout associated with this event without reading it. */
public long getStdOutSize() throws IOException {
FileOutErr outErr = getProperty(FileOutErr.class);
@@ -206,6 +217,16 @@
return outErr.outAsBytes();
}
+ /**
+ * Gets the path to the stderr associated with this event (which the caller must not access), or
+ * null if there is no such path.
+ */
+ @Nullable
+ public PathFragment getStdErrPathFragment() {
+ FileOutErr outErr = getProperty(FileOutErr.class);
+ return outErr == null ? null : outErr.getErrorPathFragment();
+ }
+
/** Gets the size of the stderr associated with this event without reading it. */
public long getStdErrSize() throws IOException {
FileOutErr outErr = getProperty(FileOutErr.class);
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/UiEventHandler.java b/src/main/java/com/google/devtools/build/lib/runtime/UiEventHandler.java
index 21fd0ba..362515e 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/UiEventHandler.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/UiEventHandler.java
@@ -383,7 +383,8 @@
}
@Nullable
- private byte[] getContentIfSmallEnough(String name, long size, Supplier<byte[]> getContent) {
+ private byte[] getContentIfSmallEnough(
+ String name, long size, Supplier<byte[]> getContent, Supplier<PathFragment> getPath) {
if (size == 0) {
// Avoid any possible I/O when we know it'll be empty anyway.
return null;
@@ -392,7 +393,10 @@
if (size < maxStdoutErrBytes) {
return getContent.get();
} else {
- return (name + " exceeds maximum size of " + maxStdoutErrBytes + " bytes; skipping")
+ return String.format(
+ "%s (%s) exceeds maximum size of --experimental_ui_max_stdouterr_bytes=%d bytes;"
+ + " skipping\n",
+ name, getPath.get(), maxStdoutErrBytes)
.getBytes(StandardCharsets.ISO_8859_1);
}
}
@@ -408,8 +412,12 @@
byte[] stdout = null;
byte[] stderr = null;
if (event.hasStdoutStderr()) {
- stdout = getContentIfSmallEnough("stdout", event.getStdOutSize(), event::getStdOut);
- stderr = getContentIfSmallEnough("stderr", event.getStdErrSize(), event::getStdErr);
+ stdout =
+ getContentIfSmallEnough(
+ "stdout", event.getStdOutSize(), event::getStdOut, event::getStdOutPathFragment);
+ stderr =
+ getContentIfSmallEnough(
+ "stderr", event.getStdErrSize(), event::getStdErr, event::getStdErrPathFragment);
}
if (debugAllEvents) {
diff --git a/src/main/java/com/google/devtools/build/lib/util/io/FileOutErr.java b/src/main/java/com/google/devtools/build/lib/util/io/FileOutErr.java
index e44f0f7..5a047e5 100644
--- a/src/main/java/com/google/devtools/build/lib/util/io/FileOutErr.java
+++ b/src/main/java/com/google/devtools/build/lib/util/io/FileOutErr.java
@@ -20,6 +20,7 @@
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
@@ -111,7 +112,8 @@
}
/**
- * Returns the {@link Path} this OutErr uses to buffer stdout
+ * Returns the path this OutErr uses to buffer stdout, marking the file as "accessed" because the
+ * caller has unrestricted access to the underlying file.
*
* <p>The user must ensure that no other process is writing to the files at time of creation.
*
@@ -121,13 +123,25 @@
return getFileOutputStream().getFile();
}
+ /**
+ * Returns the path this OutErr uses to buffer stdout without marking the file as "accessed".
+ *
+ * <p>The user must ensure that no other process is writing to the files at time of creation.
+ *
+ * @return the path object with the contents of stdout
+ */
+ public PathFragment getOutputPathFragment() {
+ return getFileOutputStream().getFileUnsafe().asFragment();
+ }
+
/** Returns the length of the stdout contents. */
public long outSize() throws IOException {
return getFileOutputStream().getRecordedOutputSize();
}
/**
- * Returns the {@link Path} this OutErr uses to buffer stderr.
+ * Returns the path this OutErr uses to buffer stderr, marking the file as "accessed" because the
+ * caller has unrestricted access to the underlying file.
*
* @return the path object with the contents of stderr
*/
@@ -135,6 +149,15 @@
return getFileErrorStream().getFile();
}
+ /**
+ * Returns the path this OutErr uses to buffer stderr without marking the file as "accessed".
+ *
+ * @return the path object with the contents of stderr
+ */
+ public PathFragment getErrorPathFragment() {
+ return getFileErrorStream().getFileUnsafe().asFragment();
+ }
+
public byte[] outAsBytes() {
return getFileOutputStream().getRecordedOutput();
}
diff --git a/src/test/shell/integration/ui_test.sh b/src/test/shell/integration/ui_test.sh
index c394f40..2f8670e 100755
--- a/src/test/shell/integration/ui_test.sh
+++ b/src/test/shell/integration/ui_test.sh
@@ -563,13 +563,13 @@
//outs:short-stdout-long-stderr \
>"${TEST_log}" 2>&1 || fail "build failed"
expect_log 'abc'
- expect_log 'stderr exceeds maximum size'
+ expect_log 'stderr .*/actions/stderr-.* exceeds maximum size'
bazel build --experimental_ui_max_stdouterr_bytes=5 \
//outs:long-stdout-short-stderr \
>"${TEST_log}" 2>&1 || fail "build failed"
expect_log 'abc'
- expect_log 'stdout exceeds maximum size'
+ expect_log 'stdout .*/actions/stdout-.* exceeds maximum size'
}
function test_max_stdouterr_bytes_is_for_individual_outputs() {