Enable local action execution statistics collection for sandboxed actions that use either the LinuxSandboxedSpawnRunner or the ProcessWrapperSandboxedSpawnRunner.

In particular, record metrics for user and system CPU execution time, block I/O and involuntary context switches.

This feature is guarded behind a new option, --experimental_collect_local_sandbox_action_metrics.

Note: We still need to enable execution statistics for the DarwinSandboxedSpawnRunner in a later change.

RELNOTES: None.
PiperOrigin-RevId: 179976217
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java
index 7a84431..526f155 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java
@@ -22,6 +22,8 @@
 import com.google.devtools.build.lib.vfs.FileSystemUtils;
 import com.google.devtools.build.lib.vfs.Path;
 import java.io.IOException;
+import java.time.Duration;
+import java.util.Optional;
 
 /** Strategy that uses sandboxing to execute a process. */
 // TODO(ulfjack): This class only exists for this annotation. Find a better way to handle this!
@@ -39,8 +41,48 @@
     return "sandboxed";
   }
 
+  /**
+   * Creates a sandboxed spawn runner that uses the {@code linux-sandbox} tool. If a spawn exceeds
+   * its timeout, then it will be killed instantly.
+   *
+   * @param cmdEnv the command environment to use
+   * @param sandboxBase path to the sandbox base directory
+   * @param productName the product name to use
+   */
   static LinuxSandboxedSpawnRunner create(
-      CommandEnvironment cmdEnv, Path sandboxBase, String productName, int timeoutGraceSeconds)
+      CommandEnvironment cmdEnv, Path sandboxBase, String productName) throws IOException {
+    return create(cmdEnv, sandboxBase, productName, Optional.empty());
+  }
+
+  /**
+   * Creates a sandboxed spawn runner that uses the {@code linux-sandbox} tool. If a spawn exceeds
+   * its timeout, then it will be killed after the specified delay.
+   *
+   * @param cmdEnv the command environment to use
+   * @param sandboxBase path to the sandbox base directory
+   * @param productName the product name to use
+   * @param timeoutKillDelay an additional grace period before killing timing out commands
+   */
+  static LinuxSandboxedSpawnRunner create(
+      CommandEnvironment cmdEnv, Path sandboxBase, String productName, Duration timeoutKillDelay)
+      throws IOException {
+    return create(cmdEnv, sandboxBase, productName, Optional.of(timeoutKillDelay));
+  }
+
+  /**
+   * Creates a sandboxed spawn runner that uses the {@code linux-sandbox} tool.
+   *
+   * @param cmdEnv the command environment to use
+   * @param sandboxBase path to the sandbox base directory
+   * @param productName the product name to use
+   * @param timeoutKillDelay an optional, additional grace period before killing timing out
+   *     commands. If not present, then no grace period is used and commands are killed instantly.
+   */
+  static LinuxSandboxedSpawnRunner create(
+      CommandEnvironment cmdEnv,
+      Path sandboxBase,
+      String productName,
+      Optional<Duration> timeoutKillDelay)
       throws IOException {
     Path inaccessibleHelperFile = sandboxBase.getRelative("inaccessibleHelperFile");
     FileSystemUtils.touchFile(inaccessibleHelperFile);
@@ -60,6 +102,6 @@
         productName,
         inaccessibleHelperFile,
         inaccessibleHelperDir,
-        timeoutGraceSeconds);
+        timeoutKillDelay);
   }
 }