@@ -10,7 +10,6 @@ use std::{
1010    sync:: LazyLock , 
1111} ; 
1212
13- use  anyhow:: Context ; 
1413use  camino:: { Utf8Path ,  Utf8PathBuf } ; 
1514use  fs_err:: File ; 
1615use  illumos_utils:: zfs:: { 
@@ -452,11 +451,11 @@ impl LogsHandle {
452451        service :  & str , 
453452        zip :  & mut  zip:: ZipWriter < W > , 
454453        log_snapshots :  & mut  LogSnapshots , 
455-         logfile :  & Utf8Path , 
454+         logfile :  & LogFile , 
456455        logtype :  LogType , 
457456    )  -> Result < ( ) ,  LogError >  { 
458457        let  snapshot_logfile =
459-             self . find_log_in_snapshot ( log_snapshots,  logfile) . await ?; 
458+             self . find_log_in_snapshot ( log_snapshots,  & logfile. path ) . await ?; 
460459
461460        if  logtype == LogType :: Current  { 
462461            // Since we are processing the current log files in a zone we need 
@@ -502,13 +501,24 @@ impl LogsHandle {
502501                        . filter ( |f| is_log_file ( f. path ( ) ,  filename) ) 
503502                    { 
504503                        let  logfile = f. path ( ) ; 
504+                         let  system_mtime =
505+                             f. metadata ( ) . and_then ( |m| m. modified ( ) ) . inspect_err ( |e| { 
506+                                 warn ! ( & self . log,  "sled-diagnostic failed to get mtime of logfile" ; 
507+                                     "error"  => %e, 
508+                                     "logfile"  => %logfile, 
509+                                 ) ; 
510+                             } ) . ok ( ) ; 
511+                         let  mtime = system_mtime
512+                             . and_then ( |m| jiff:: Timestamp :: try_from ( m) . ok ( ) ) ; 
513+ 
505514                        if  logfile. is_file ( )  { 
506515                            write_log_to_zip ( 
507516                                & self . log , 
508517                                service, 
509518                                zip, 
510519                                LogType :: Current , 
511520                                logfile, 
521+                                 mtime, 
512522                            ) ?; 
513523                        } 
514524                    } 
@@ -523,6 +533,7 @@ impl LogsHandle {
523533                        zip, 
524534                        logtype, 
525535                        & snapshot_logfile, 
536+                         logfile. modified , 
526537                    ) ?; 
527538                } 
528539                false  => { 
@@ -613,7 +624,7 @@ impl LogsHandle {
613624                    & service, 
614625                    & mut  zip, 
615626                    & mut  log_snapshots, 
616-                     & current. path , 
627+                     & current, 
617628                    LogType :: Current , 
618629                ) 
619630                . await ?; 
@@ -629,13 +640,13 @@ impl LogsHandle {
629640                . archived 
630641                . into_iter ( ) 
631642                . filter ( |log| log. path . as_str ( ) . contains ( "crypt/debug" ) ) 
632-                 . map ( |log| log. path ) 
633643                . collect ( ) ; 
634644
635645            // Since these logs can be spread out across multiple U.2 devices 
636646            // we need to sort them by timestamp. 
637647            archived. sort_by_key ( |log| { 
638-                 log. as_str ( ) 
648+                 log. path 
649+                     . as_str ( ) 
639650                    . rsplit_once ( "." ) 
640651                    . and_then ( |( _,  date) | date. parse :: < u64 > ( ) . ok ( ) ) 
641652                    . unwrap_or ( 0 ) 
@@ -704,6 +715,7 @@ fn write_log_to_zip<W: Write + Seek>(
704715    zip :  & mut  zip:: ZipWriter < W > , 
705716    logtype :  LogType , 
706717    snapshot_logfile :  & Utf8Path , 
718+     mtime :  Option < jiff:: Timestamp > , 
707719)  -> Result < ( ) ,  LogError >  { 
708720    let  Some ( log_name)  = snapshot_logfile. file_name ( )  else  { 
709721        warn ! ( 
@@ -717,23 +729,18 @@ fn write_log_to_zip<W: Write + Seek>(
717729
718730    let  mut  src = File :: open ( & snapshot_logfile) ?; 
719731
720-     let  mtime = get_log_mtime ( snapshot_logfile) 
721-         . inspect_err ( |e| { 
722-             warn ! ( 
723-                 logger, 
724-                 "sled-diagnostics unable to get mtime for logfile" ; 
725-                 "error"  => %e, 
726-                 "logfile"  => %snapshot_logfile, 
727-             ) ; 
732+     let  zip_mtime = mtime
733+         . and_then ( |ts| { 
734+             let  zoned = ts. in_tz ( "UTC" ) . ok ( ) ?; 
735+             zip:: DateTime :: try_from ( zoned. datetime ( ) ) . ok ( ) 
728736        } ) 
729-         . ok ( ) 
730-         . unwrap_or_else ( zip:: DateTime :: default_for_write) ; 
737+         . unwrap_or_else ( zip:: DateTime :: default) ; 
731738
732739    let  zip_path = format ! ( "{service}/{logtype}/{log_name}" ) ; 
733740    zip. start_file_from_path ( 
734741        zip_path, 
735742        FullFileOptions :: default ( ) 
736-             . last_modified_time ( mtime ) 
743+             . last_modified_time ( zip_mtime ) 
737744            . compression_method ( zip:: CompressionMethod :: Zstd ) 
738745            . compression_level ( Some ( 3 ) ) 
739746            // NB: From the docs 
@@ -761,17 +768,6 @@ fn write_log_to_zip<W: Write + Seek>(
761768    Ok ( ( ) ) 
762769} 
763770
764- fn  get_log_mtime ( log_path :  & Utf8Path )  -> anyhow:: Result < zip:: DateTime >  { 
765-     let  mtime = log_path
766-         . metadata ( ) 
767-         . and_then ( |s| s. modified ( ) ) 
768-         . context ( "failed to stat path" ) ?; 
769- 
770-     let  datetime:  chrono:: DateTime < chrono:: Utc >  = mtime. into ( ) ; 
771-     zip:: DateTime :: try_from ( datetime. naive_utc ( ) ) 
772-         . context ( "failed to convert file mtime to zip-compatible time" ) 
773- } 
774- 
775771/// A log file that is found in oxlog's "extra" bucket of service logs. 
776772#[ derive( Debug ,  PartialEq ) ]  
777773enum  ExtraLogKind < ' a >  { 
@@ -783,8 +779,8 @@ enum ExtraLogKind<'a> {
783779
784780#[ derive( Debug ,  Default ,  PartialEq ) ]  
785781struct  ExtraLogs < ' a >  { 
786-     current :  Option < & ' a  Utf8Path > , 
787-     rotated :  Vec < & ' a  Utf8Path > , 
782+     current :  Option < & ' a  LogFile > , 
783+     rotated :  Vec < & ' a  LogFile > , 
788784} 
789785
790786fn  sort_extra_logs < ' a > ( 
@@ -806,15 +802,15 @@ fn sort_extra_logs<'a>(
806802                        warn ! ( 
807803                            logger, 
808804                            "found multiple current log files for {name}" ; 
809-                             "old"  => %old_path, 
805+                             "old"  => %old_path. path , 
810806                            "new"  => %log. path, 
811807                        ) ; 
812808                    } 
813-                     entry. current  = Some ( & log. path ) ; 
809+                     entry. current  = Some ( & log) ; 
814810                } 
815811                ExtraLogKind :: Rotated  {  name,  log }  => { 
816812                    let  entry = res. entry ( name) . or_default ( ) ; 
817-                     entry. rotated . push ( & log. path ) ; 
813+                     entry. rotated . push ( & log) ; 
818814                } 
819815            } 
820816        } 
@@ -864,9 +860,9 @@ fn sort_cockroach_extra_logs(logs: &[LogFile]) -> HashMap<&str, ExtraLogs<'_>> {
864860            let  entry = interested. entry ( prefix) . or_default ( ) ; 
865861
866862            if  file_name == format ! ( "{prefix}.log" )  { 
867-                 entry. current  = Some ( log. path . as_path ( ) ) ; 
863+                 entry. current  = Some ( log) ; 
868864            }  else  { 
869-                 entry. rotated . push ( log. path . as_path ( ) ) ; 
865+                 entry. rotated . push ( log) ; 
870866            } 
871867        } 
872868    } 
@@ -943,52 +939,30 @@ mod test {
943939            "bogus.log" , 
944940            "some/dir" 
945941        ] . into_iter ( ) . map ( |l| { 
946-                 oxlog:: LogFile  {  path :  Utf8PathBuf :: from ( l) ,  size :  None ,  modified :  None  } 
947-             } ) . collect ( ) ; 
942+             oxlog:: LogFile  {  path :  Utf8PathBuf :: from ( l) ,  size :  None ,  modified :  None  } 
943+         } ) . collect ( ) ; 
944+         let  logs_map:  HashMap < _ ,  _ >  =
945+             logs. iter ( ) . map ( |l| ( l. path . as_str ( ) ,  l) ) . collect ( ) ; 
948946
949947        let  mut  expected:  HashMap < & str ,  ExtraLogs < ' _ > >  = HashMap :: new ( ) ; 
950948
951949        // cockroach 
952950        expected. entry ( "cockroach" ) . or_default ( ) . current  =
953-             Some ( Utf8Path :: new ( "cockroach.log" ) ) ; 
954-         expected
955-             . entry ( "cockroach" ) 
956-             . or_default ( ) 
957-             . rotated 
958-             . push ( Utf8Path :: new ( "cockroach.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2025-01-31T17_11_45Z.011435.log" ) ) ; 
959-         expected
960-             . entry ( "cockroach" ) 
961-             . or_default ( ) 
962-             . rotated 
963-             . push ( Utf8Path :: new ( "cockroach.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2025-02-01T01_51_51Z.011486.log" ) ) ; 
951+             Some ( & logs_map[ "cockroach.log" ] ) ; 
952+         expected. entry ( "cockroach" ) . or_default ( ) . rotated . push ( & logs_map[ "cockroach.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2025-01-31T17_11_45Z.011435.log" ] ) ; 
953+         expected. entry ( "cockroach" ) . or_default ( ) . rotated . push ( & logs_map[ "cockroach.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2025-02-01T01_51_51Z.011486.log" ] ) ; 
964954
965955        // cockroach-health 
966956        expected. entry ( "cockroach-health" ) . or_default ( ) . current  =
967-             Some ( Utf8Path :: new ( "cockroach-health.log" ) ) ; 
968-         expected
969-             . entry ( "cockroach-health" ) 
970-             . or_default ( ) 
971-             . rotated 
972-             . push ( Utf8Path :: new ( "cockroach-health.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2025-01-31T21_43_26Z.011435.log" ) ) ; 
973-         expected
974-             . entry ( "cockroach-health" ) 
975-             . or_default ( ) 
976-             . rotated 
977-             . push ( Utf8Path :: new ( "cockroach-health.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2025-02-01T01_51_53Z.011486.log" ) ) ; 
957+             Some ( & logs_map[ "cockroach-health.log" ] ) ; 
958+         expected. entry ( "cockroach-health" ) . or_default ( ) . rotated . push ( & logs_map[ "cockroach-health.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2025-01-31T21_43_26Z.011435.log" ] ) ; 
959+         expected. entry ( "cockroach-health" ) . or_default ( ) . rotated . push ( & logs_map[ "cockroach-health.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2025-02-01T01_51_53Z.011486.log" ] ) ; 
978960
979961        // cockroach-stderr 
980962        expected. entry ( "cockroach-stderr" ) . or_default ( ) . current  =
981-             Some ( Utf8Path :: new ( "cockroach-stderr.log" ) ) ; 
982-         expected
983-             . entry ( "cockroach-stderr" ) 
984-             . or_default ( ) 
985-             . rotated 
986-             . push ( Utf8Path :: new ( "cockroach-stderr.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2023-08-30T18_56_19Z.011950.log" ) ) ; 
987-         expected
988-             . entry ( "cockroach-stderr" ) 
989-             . or_default ( ) 
990-             . rotated 
991-             . push ( Utf8Path :: new ( "cockroach-stderr.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2023-08-31T02_59_24Z.010479.log" ) ) ; 
963+             Some ( & logs_map[ "cockroach-stderr.log" ] ) ; 
964+         expected. entry ( "cockroach-stderr" ) . or_default ( ) . rotated . push ( & logs_map[ "cockroach-stderr.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2023-08-30T18_56_19Z.011950.log" ] ) ; 
965+         expected. entry ( "cockroach-stderr" ) . or_default ( ) . rotated . push ( & logs_map[ "cockroach-stderr.oxzcockroachdba3628a56-6f85-43b5-be50-71d8f0e04877.root.2023-08-31T02_59_24Z.010479.log" ] ) ; 
992966
993967        let  extra = sort_cockroach_extra_logs ( logs. as_slice ( ) ) ; 
994968        assert_eq ! ( 
@@ -1254,14 +1228,19 @@ mod illumos_tests {
12541228            let  zipfile_path = mountpoint. join ( "test.zip" ) ; 
12551229            let  zipfile = File :: create_new ( & zipfile_path) . unwrap ( ) ; 
12561230            let  mut  zip = ZipWriter :: new ( zipfile) ; 
1231+             let  log = LogFile  { 
1232+                 path :  mountpoint
1233+                     . join ( format ! ( "var/svc/log/{}" ,  logfile_to_data[ 0 ] . 0 ) ) , 
1234+                 size :  None , 
1235+                 modified :  None , 
1236+             } ; 
12571237
12581238            loghandle
12591239                . process_logs ( 
12601240                    "mg-ddm" , 
12611241                    & mut  zip, 
12621242                    & mut  log_snapshots, 
1263-                     & mountpoint
1264-                         . join ( format ! ( "var/svc/log/{}" ,  logfile_to_data[ 0 ] . 0 ) ) , 
1243+                     & log, 
12651244                    LogType :: Current , 
12661245                ) 
12671246                . await 
@@ -1348,13 +1327,14 @@ mod illumos_tests {
13481327            let  zipfile_path = mountpoint. join ( "test.zip" ) ; 
13491328            let  zipfile = File :: create_new ( & zipfile_path) . unwrap ( ) ; 
13501329            let  mut  zip = ZipWriter :: new ( zipfile) ; 
1330+             let  log = LogFile  {  path :  logfile,  size :  None ,  modified :  None  } ; 
13511331
13521332            loghandle
13531333                . process_logs ( 
13541334                    "mg-ddm" , 
13551335                    & mut  zip, 
13561336                    & mut  log_snapshots, 
1357-                     & logfile , 
1337+                     & log , 
13581338                    LogType :: Current , 
13591339                ) 
13601340                . await 
0 commit comments