1- pub use tracing:: { debug, error, info, warn, Level } ;
2- use tracing_error:: ErrorLayer ;
3- use tracing_subscriber:: {
4- fmt, layer:: SubscriberExt , prelude:: * , util:: SubscriberInitExt , EnvFilter ,
5- } ;
6-
71use crate :: {
82 print_to_terminal,
93 vfs:: { create_drive, open_file, File } ,
104 Address , Request ,
115} ;
6+ pub use tracing:: { debug, error, info, warn, Level } ;
7+ use tracing_error:: ErrorLayer ;
8+ use tracing_subscriber:: {
9+ fmt, layer:: SubscriberExt , prelude:: * , util:: SubscriberInitExt , EnvFilter ,
10+ } ;
1211
1312pub struct RemoteLogSettings {
1413 pub target : Address ,
@@ -25,10 +24,12 @@ pub struct RemoteWriterMaker {
2524
2625pub struct FileWriter {
2726 pub file : File ,
27+ pub max_size : u64 ,
2828}
2929
3030pub struct FileWriterMaker {
3131 pub file : File ,
32+ pub max_size : u64 ,
3233}
3334
3435pub struct TerminalWriter {
@@ -65,6 +66,28 @@ impl<'a> tracing_subscriber::fmt::MakeWriter<'a> for RemoteWriterMaker {
6566impl std:: io:: Write for FileWriter {
6667 fn write ( & mut self , buf : & [ u8 ] ) -> std:: io:: Result < usize > {
6768 // TODO: use non-blocking call instead? (.append() `send_and_await()`s)
69+ let metadata = self
70+ . file
71+ . metadata ( )
72+ . map_err ( |e| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , e) ) ?;
73+
74+ if metadata. len > self . max_size {
75+ // Get current contents
76+ let contents = self
77+ . file
78+ . read ( )
79+ . map_err ( |e| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , e) ) ?;
80+
81+ // Take second half of file
82+ let half_len = contents. len ( ) / 2 ;
83+ let new_contents = & contents[ half_len..] ;
84+
85+ // Truncate and write back second half
86+ self . file
87+ . write ( new_contents)
88+ . map_err ( |e| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , e) ) ?;
89+ }
90+
6891 self . file
6992 . append ( buf)
7093 . map_err ( |e| std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , e) ) ?;
@@ -82,6 +105,7 @@ impl<'a> tracing_subscriber::fmt::MakeWriter<'a> for FileWriterMaker {
82105 fn make_writer ( & ' a self ) -> Self :: Writer {
83106 FileWriter {
84107 file : File :: new ( self . file . path . clone ( ) , self . file . timeout ) ,
108+ max_size : self . max_size ,
85109 }
86110 }
87111}
@@ -114,17 +138,21 @@ impl<'a> tracing_subscriber::fmt::MakeWriter<'a> for TerminalWriterMaker {
114138/// Logs will be printed to terminal as appropriate depending on given level.
115139/// Logs will be logged into the logging file as appropriate depending on the given level.
116140///
141+ /// If `max_log_file_size` is provided, the log file will be rotated when it reaches
142+ /// the given size. The default size is 1MB.
143+ ///
117144/// The logging file lives in the node's `vfs/` directory, specifically at
118145/// `node/vfs/package:publisher.os/log/process.log`, where `node` is your node's home
119146/// directory, `package` is the package name, `publisher.os` is the publisher of the
120147/// package, and `process` is the process name of the process doing the logging.
121148pub fn init_logging (
122- our : & Address ,
123149 file_level : Level ,
124150 terminal_level : Level ,
125151 remote : Option < RemoteLogSettings > ,
126152 terminal_levels_mapping : Option < ( u8 , u8 , u8 , u8 ) > ,
153+ max_log_file_size : Option < u64 > ,
127154) -> anyhow:: Result < ( ) > {
155+ let our = crate :: our ( ) ;
128156 let log_dir_path = create_drive ( our. package_id ( ) , "log" , None ) ?;
129157 let log_file_path = format ! ( "{log_dir_path}/{}.log" , our. process( ) ) ;
130158 let log_file = open_file ( & log_file_path, true , None ) ?;
@@ -142,7 +170,10 @@ pub fn init_logging(
142170 let debug_filter = tracing_subscriber:: filter:: filter_fn ( |metadata : & tracing:: Metadata < ' _ > | {
143171 metadata. level ( ) == & Level :: DEBUG
144172 } ) ;
145- let file_writer_maker = FileWriterMaker { file : log_file } ;
173+ let file_writer_maker = FileWriterMaker {
174+ file : log_file,
175+ max_size : max_log_file_size. unwrap_or ( 1024 * 1024 ) ,
176+ } ;
146177 let ( error, warn, info, debug) = terminal_levels_mapping. unwrap_or_else ( || ( 0 , 1 , 2 , 3 ) ) ;
147178 let error_terminal_writer_maker = TerminalWriterMaker { level : error } ;
148179 let warn_terminal_writer_maker = TerminalWriterMaker { level : warn } ;
0 commit comments