mirror of
https://github.com/openai/codex.git
synced 2026-02-01 22:47:52 +00:00
emit a metric when we can't spawn powershell (#10125)
This will help diagnose and measure the impact of a user-reported bug with the elevated sandbox and powershell
This commit is contained in:
@@ -232,6 +232,72 @@ pub(crate) async fn execute_exec_env(
|
||||
finalize_exec_result(raw_output_result, sandbox, duration)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn extract_create_process_as_user_error_code(err: &str) -> Option<String> {
|
||||
let marker = "CreateProcessAsUserW failed: ";
|
||||
let start = err.find(marker)? + marker.len();
|
||||
let tail = &err[start..];
|
||||
let digits: String = tail.chars().take_while(char::is_ascii_digit).collect();
|
||||
if digits.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(digits)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn windowsapps_path_kind(path: &str) -> &'static str {
|
||||
let lower = path.to_ascii_lowercase();
|
||||
if lower.contains("\\program files\\windowsapps\\") {
|
||||
return "windowsapps_package";
|
||||
}
|
||||
if lower.contains("\\appdata\\local\\microsoft\\windowsapps\\") {
|
||||
return "windowsapps_alias";
|
||||
}
|
||||
if lower.contains("\\windowsapps\\") {
|
||||
return "windowsapps_other";
|
||||
}
|
||||
"other"
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn record_windows_sandbox_spawn_failure(
|
||||
command_path: Option<&str>,
|
||||
windows_sandbox_level: codex_protocol::config_types::WindowsSandboxLevel,
|
||||
err: &str,
|
||||
) {
|
||||
let Some(error_code) = extract_create_process_as_user_error_code(err) else {
|
||||
return;
|
||||
};
|
||||
let path = command_path.unwrap_or("unknown");
|
||||
let exe = Path::new(path)
|
||||
.file_name()
|
||||
.and_then(|name| name.to_str())
|
||||
.unwrap_or("unknown")
|
||||
.to_ascii_lowercase();
|
||||
let path_kind = windowsapps_path_kind(path);
|
||||
let level = if matches!(
|
||||
windows_sandbox_level,
|
||||
codex_protocol::config_types::WindowsSandboxLevel::Elevated
|
||||
) {
|
||||
"elevated"
|
||||
} else {
|
||||
"legacy"
|
||||
};
|
||||
if let Some(metrics) = codex_otel::metrics::global() {
|
||||
let _ = metrics.counter(
|
||||
"codex.windows_sandbox.createprocessasuserw_failed",
|
||||
1,
|
||||
&[
|
||||
("error_code", error_code.as_str()),
|
||||
("path_kind", path_kind),
|
||||
("exe", exe.as_str()),
|
||||
("level", level),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
async fn exec_windows_sandbox(
|
||||
params: ExecParams,
|
||||
@@ -265,7 +331,9 @@ async fn exec_windows_sandbox(
|
||||
"windows sandbox: failed to resolve codex_home: {err}"
|
||||
)))
|
||||
})?;
|
||||
let use_elevated = matches!(windows_sandbox_level, WindowsSandboxLevel::Elevated);
|
||||
let command_path = command.first().cloned();
|
||||
let sandbox_level = windows_sandbox_level;
|
||||
let use_elevated = matches!(sandbox_level, WindowsSandboxLevel::Elevated);
|
||||
let spawn_res = tokio::task::spawn_blocking(move || {
|
||||
if use_elevated {
|
||||
run_windows_sandbox_capture_elevated(
|
||||
@@ -294,6 +362,11 @@ async fn exec_windows_sandbox(
|
||||
let capture = match spawn_res {
|
||||
Ok(Ok(v)) => v,
|
||||
Ok(Err(err)) => {
|
||||
record_windows_sandbox_spawn_failure(
|
||||
command_path.as_deref(),
|
||||
sandbox_level,
|
||||
&err.to_string(),
|
||||
);
|
||||
return Err(CodexErr::Io(io::Error::other(format!(
|
||||
"windows sandbox: {err}"
|
||||
))));
|
||||
|
||||
Reference in New Issue
Block a user