@@ -4,7 +4,7 @@ use std::collections::HashMap;
44use std:: fs:: { self , File , OpenOptions } ;
55use std:: io:: Write ;
66use std:: path:: { Path , PathBuf } ;
7- use std:: time:: Duration ;
7+ use std:: time:: { Duration , Instant } ;
88use tokio:: process:: Command ;
99use tokio:: time:: sleep;
1010use 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+
781800fn 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