diff --git a/crates/arc-workflows/src/cli/run.rs b/crates/arc-workflows/src/cli/run.rs index 445c067e1..19fa5666e 100644 --- a/crates/arc-workflows/src/cli/run.rs +++ b/crates/arc-workflows/src/cli/run.rs @@ -342,12 +342,13 @@ pub async fn run_command( } // 3. Create logs directory + let run_id = ulid::Ulid::new().to_string(); let logs_dir = args.logs_dir.unwrap_or_else(|| { let base = dirs::home_dir() .expect("could not determine home directory") .join(".arc") .join("logs"); - base.join(format!("arc-run-{}", Local::now().format("%Y%m%d-%H%M%S"))) + base.join(format!("{}-{}", Local::now().format("%Y%m%d"), run_id)) }); tokio::fs::create_dir_all(&logs_dir).await?; tokio::fs::write(logs_dir.join("graph.dot"), &source).await?; @@ -361,8 +362,6 @@ pub async fn run_command( // Create progress UI (used for both normal and verbose modes) let is_tty = std::io::stderr().is_terminal(); let progress_ui = Arc::new(Mutex::new(progress::ProgressUI::new(is_tty, args.verbose))); - - let run_id = ulid::Ulid::new().to_string(); { let mut ui = progress_ui.lock().expect("progress lock poisoned"); ui.show_run_id(&run_id); @@ -1118,8 +1117,9 @@ async fn run_from_branch( .join(".arc") .join("logs"); base.join(format!( - "arc-resume-{}", - chrono::Local::now().format("%Y%m%d-%H%M%S") + "{}-{}", + chrono::Local::now().format("%Y%m%d"), + run_id )) }); tokio::fs::create_dir_all(&logs_dir).await?; diff --git a/crates/arc-workflows/src/cli/runs.rs b/crates/arc-workflows/src/cli/runs.rs index 4b5c33413..e3e6f7145 100644 --- a/crates/arc-workflows/src/cli/runs.rs +++ b/crates/arc-workflows/src/cli/runs.rs @@ -327,7 +327,7 @@ mod tests { make_run_dir( base, - "arc-run-20260101-120000", + "20260101-ABC123", Some(serde_json::json!({ "run_id": "abc123", "workflow_name": "my-pipeline", @@ -366,7 +366,7 @@ mod tests { make_run_dir( base, - "arc-run-running", + "20260115-RUNNING1", Some(serde_json::json!({ "run_id": "running-1", "workflow_name": "pipeline-a", @@ -516,7 +516,7 @@ mod tests { let dir = make_run_dir( base, - "arc-run-20250101-120000", + "20250101-TOPRUNE", Some(serde_json::json!({ "run_id": "to-prune", "workflow_name": "old-pipeline", @@ -552,7 +552,7 @@ mod tests { let dir = make_run_dir( base, - "arc-run-20250101-120000", + "20250101-TOPRUNE", Some(serde_json::json!({ "run_id": "to-prune", "workflow_name": "old-pipeline", @@ -570,7 +570,7 @@ mod tests { // Also add a run that should NOT be pruned (too new) let keep_dir = make_run_dir( base, - "arc-run-20260301-120000", + "20260301-KEEPTHIS", Some(serde_json::json!({ "run_id": "keep-this", "workflow_name": "new-pipeline", diff --git a/docs/reference/logs-directory.mdx b/docs/reference/logs-directory.mdx index ba11f4796..bd1142ea7 100644 --- a/docs/reference/logs-directory.mdx +++ b/docs/reference/logs-directory.mdx @@ -20,10 +20,10 @@ The log level defaults to `info`. Set `ARC_LOG=debug` or pass `--debug` for verb Each `arc run` invocation creates a timestamped directory: ``` -~/.arc/logs/arc-run-20260307-143022/ +~/.arc/logs/20260307-01JQXYZ123ABC456DEF789/ ``` -The naming format is `arc-run-YYYYMMDD-HHMMSS`. You can override the location with `--logs-dir`. +The naming format is `YYYYMMDD-{run_id}`, where `run_id` is the ULID assigned to the run. You can override the location with `--logs-dir`. ### Root-level files @@ -94,7 +94,7 @@ arc ps --filter workflow=my-workflow ``` ~/.arc/logs/ ├── 2026-03-07.log # Daily CLI log -├── arc-run-20260307-143022/ # One directory per run +├── 20260307-01JQXYZ123ABC456DEF789/ # One directory per run │ ├── manifest.json │ ├── graph.dot │ ├── run.pid