Skip to content

Commit 6ae66d1

Browse files
committed
feat(logging): add task duration to finish markers
Include elapsed time in build and job finish log markers for easier performance analysis.
1 parent a6ed8cb commit 6ae66d1

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

src/actor/job/executor.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::collections::HashMap;
44
use std::fs::{self, File, OpenOptions};
55
use std::io::Write;
66
use std::path::{Path, PathBuf};
7-
use std::time::Duration;
7+
use std::time::{Duration, Instant};
88
use tokio::process::Command;
99
use tokio::time::sleep;
1010
use tracing::{debug, error, info, warn};
@@ -59,15 +59,18 @@ pub async fn execute_build(job: &Job, sot_path: &Path, runner: &RunnerConfig) ->
5959
write_log_marker(file, &runner.timezone, job.timezone.as_ref(), "Build started");
6060
}
6161

62+
let start_time = Instant::now();
6263
let result = run_build_command(job, build_config, &build_dir, sot_path, runner).await;
64+
let duration = start_time.elapsed();
6365

6466
match &result {
6567
BuildCommandResult::Completed(output) if output.status.success() => {
6668
info!(target: "rollcron::job", job_id = %job.id, "Build completed");
6769
if let Some(ref mut file) = log_file {
6870
let _ = file.write_all(&output.stdout);
6971
let _ = file.write_all(&output.stderr);
70-
write_log_marker(file, &runner.timezone, job.timezone.as_ref(), "Build finished (success)");
72+
let marker = format!("Build finished (success) [{}]", format_duration(duration));
73+
write_log_marker(file, &runner.timezone, job.timezone.as_ref(), &marker);
7174
}
7275
BuildResult::Success
7376
}
@@ -83,7 +86,7 @@ pub async fn execute_build(job: &Job, sot_path: &Path, runner: &RunnerConfig) ->
8386
if let Some(ref mut file) = log_file {
8487
let _ = file.write_all(&output.stdout);
8588
let _ = file.write_all(&output.stderr);
86-
let marker = format!("Build finished (failed, exit code {:?})", output.status.code());
89+
let marker = format!("Build finished (failed, exit code {:?}) [{}]", output.status.code(), format_duration(duration));
8790
write_log_marker(file, &runner.timezone, job.timezone.as_ref(), &marker);
8891
}
8992

@@ -116,7 +119,7 @@ pub async fn execute_build(job: &Job, sot_path: &Path, runner: &RunnerConfig) ->
116119

117120
if let Some(ref mut file) = log_file {
118121
let _ = writeln!(file, "[rollcron] Error: {}", e);
119-
let marker = format!("Build finished (error: {})", e);
122+
let marker = format!("Build finished (error: {}) [{}]", e, format_duration(duration));
120123
write_log_marker(file, &runner.timezone, job.timezone.as_ref(), &marker);
121124
}
122125

@@ -148,7 +151,7 @@ pub async fn execute_build(job: &Job, sot_path: &Path, runner: &RunnerConfig) ->
148151

149152
if let Some(ref mut file) = log_file {
150153
let _ = writeln!(file, "[rollcron] Timeout after {:?}", build_config.timeout);
151-
let marker = format!("Build finished (timeout after {:?})", build_config.timeout);
154+
let marker = format!("Build finished (timeout after {:?}) [{}]", build_config.timeout, format_duration(duration));
152155
write_log_marker(file, &runner.timezone, job.timezone.as_ref(), &marker);
153156
}
154157

@@ -362,8 +365,10 @@ pub async fn execute_job(job: &Job, sot_path: &Path, runner: &RunnerConfig) -> b
362365
write_log_marker(file, &runner.timezone, job.timezone.as_ref(), &marker);
363366
}
364367

368+
let start_time = Instant::now();
365369
let result = run_command(job, &work_dir, sot_path, runner).await;
366-
let success = handle_result(job, &result, log_file.as_mut(), &runner.timezone);
370+
let duration = start_time.elapsed();
371+
let success = handle_result(job, &result, log_file.as_mut(), &runner.timezone, duration);
367372

368373
if success {
369374
return true;
@@ -658,7 +663,7 @@ enum CommandResult {
658663
Timeout,
659664
}
660665

661-
fn handle_result(job: &Job, result: &CommandResult, log_file: Option<&mut File>, runner_tz: &TimezoneConfig) -> bool {
666+
fn handle_result(job: &Job, result: &CommandResult, log_file: Option<&mut File>, runner_tz: &TimezoneConfig, duration: Duration) -> bool {
662667
match result {
663668
CommandResult::Completed(output) => {
664669
let stdout = String::from_utf8_lossy(&output.stdout);
@@ -669,9 +674,9 @@ fn handle_result(job: &Job, result: &CommandResult, log_file: Option<&mut File>,
669674
let _ = file.write_all(stdout.as_bytes());
670675
let _ = file.write_all(stderr.as_bytes());
671676
let marker = if success {
672-
"Job finished (success)".to_string()
677+
format!("Job finished (success) [{}]", format_duration(duration))
673678
} else {
674-
format!("Job finished (failed, exit code {:?})", output.status.code())
679+
format!("Job finished (failed, exit code {:?}) [{}]", output.status.code(), format_duration(duration))
675680
};
676681
write_log_marker(file, runner_tz, job.timezone.as_ref(), &marker);
677682
}
@@ -692,7 +697,7 @@ fn handle_result(job: &Job, result: &CommandResult, log_file: Option<&mut File>,
692697
error!(target: "rollcron::job", job_id = %job.id, error = %e, "Failed to execute");
693698
if let Some(file) = log_file {
694699
let _ = writeln!(file, "[rollcron] Error: {}", e);
695-
let marker = format!("Job finished (error: {})", e);
700+
let marker = format!("Job finished (error: {}) [{}]", e, format_duration(duration));
696701
write_log_marker(file, runner_tz, job.timezone.as_ref(), &marker);
697702
}
698703
false
@@ -701,7 +706,7 @@ fn handle_result(job: &Job, result: &CommandResult, log_file: Option<&mut File>,
701706
error!(target: "rollcron::job", job_id = %job.id, timeout = ?job.timeout, "Timeout");
702707
if let Some(file) = log_file {
703708
let _ = writeln!(file, "[rollcron] Timeout after {:?}", job.timeout);
704-
let marker = format!("Job finished (timeout after {:?})", job.timeout);
709+
let marker = format!("Job finished (timeout after {:?}) [{}]", job.timeout, format_duration(duration));
705710
write_log_marker(file, runner_tz, job.timezone.as_ref(), &marker);
706711
}
707712
false
@@ -778,6 +783,20 @@ fn format_timestamp(runner_tz: &TimezoneConfig, job_tz: Option<&TimezoneConfig>)
778783
}
779784
}
780785

786+
fn format_duration(d: Duration) -> String {
787+
let secs = d.as_secs();
788+
let millis = d.subsec_millis();
789+
if secs >= 3600 {
790+
format!("{}h {}m {}s", secs / 3600, (secs % 3600) / 60, secs % 60)
791+
} else if secs >= 60 {
792+
format!("{}m {}s", secs / 60, secs % 60)
793+
} else if secs > 0 {
794+
format!("{}.{:03}s", secs, millis)
795+
} else {
796+
format!("{}ms", millis)
797+
}
798+
}
799+
781800
fn write_log_marker(file: &mut File, runner_tz: &TimezoneConfig, job_tz: Option<&TimezoneConfig>, marker: &str) {
782801
let timestamp = format_timestamp(runner_tz, job_tz);
783802
let _ = writeln!(file, "\n[{timestamp}] === {marker} ===");

0 commit comments

Comments
 (0)