@@ -9,9 +9,14 @@ use beacon_processor::WorkEvent;
99use lighthouse_network:: NetworkGlobals ;
1010use rand_chacha:: ChaCha20Rng ;
1111use slot_clock:: ManualSlotClock ;
12- use std:: sync:: Arc ;
12+ use std:: fs:: OpenOptions ;
13+ use std:: io:: Write ;
14+ use std:: sync:: { Arc , Once } ;
1315use store:: MemoryStore ;
1416use tokio:: sync:: mpsc;
17+ use tracing_subscriber:: fmt:: MakeWriter ;
18+ use tracing_subscriber:: layer:: SubscriberExt ;
19+ use tracing_subscriber:: util:: SubscriberInitExt ;
1520use types:: { ChainSpec , ForkName , MinimalEthSpec as E } ;
1621
1722mod lookups;
@@ -65,3 +70,55 @@ struct TestRig {
6570 fork_name : ForkName ,
6671 spec : Arc < ChainSpec > ,
6772}
73+
74+ // Environment variable to read if `fork_from_env` feature is enabled.
75+ pub const FORK_NAME_ENV_VAR : & str = "FORK_NAME" ;
76+ // Environment variable specifying the log output directory in CI.
77+ pub const CI_LOGGER_DIR_ENV_VAR : & str = "CI_LOGGER_DIR" ;
78+
79+ static INIT_TRACING : Once = Once :: new ( ) ;
80+
81+ pub fn init_tracing ( ) {
82+ INIT_TRACING . call_once ( || {
83+ if std:: env:: var ( CI_LOGGER_DIR_ENV_VAR ) . is_ok ( ) {
84+ // Enable logging to log files for each test and each fork.
85+ tracing_subscriber:: registry ( )
86+ . with (
87+ tracing_subscriber:: fmt:: layer ( )
88+ . with_ansi ( false )
89+ . with_writer ( CILogWriter ) ,
90+ )
91+ . init ( ) ;
92+ }
93+ } ) ;
94+ }
95+
96+ // CILogWriter writes logs to separate files for each test and each fork.
97+ struct CILogWriter ;
98+
99+ impl < ' a > MakeWriter < ' a > for CILogWriter {
100+ type Writer = Box < dyn Write + Send > ;
101+
102+ // fmt::Layer calls this method each time an event is recorded.
103+ fn make_writer ( & ' a self ) -> Self :: Writer {
104+ let log_dir = std:: env:: var ( CI_LOGGER_DIR_ENV_VAR ) . unwrap ( ) ;
105+ let fork_name = std:: env:: var ( FORK_NAME_ENV_VAR )
106+ . map ( |s| format ! ( "{s}_" ) )
107+ . unwrap_or_default ( ) ;
108+
109+ // The current test name can be got via the thread name.
110+ let test_name = std:: thread:: current ( )
111+ . name ( )
112+ . unwrap_or ( "unnamed" )
113+ . replace ( |c : char | !c. is_alphanumeric ( ) , "_" ) ;
114+
115+ let file_path = format ! ( "{log_dir}/{fork_name}{test_name}.log" ) ;
116+ let file = OpenOptions :: new ( )
117+ . append ( true )
118+ . create ( true )
119+ . open ( & file_path)
120+ . expect ( "failed to open a log file" ) ;
121+
122+ Box :: new ( file)
123+ }
124+ }
0 commit comments